0

Linux Pocket Guide has a nice example on how to go over all the arguments in a script

for arg in $@
do
   echo "I found the argument $arg"
done

I am writing a script in which all the arguments will be text files, and I will concatenate all those text files and print them to stdout, however I should exclude the contents of the first argument. My first approach would be something like this

for arg in $@
do
   cat "$arg"

done

However, that will include the first argument, and as I mentioned, I want to print all except the first one.

1
  • 1
    As a side note, "$@" should always be quoted. Another side note, you can get the same functionality without the for loop: cat "$@".
    – jordanm
    Sep 18, 2015 at 3:40

4 Answers 4

4

You can use shift command like this:

shift
for arg in "$@"
do
    cat "$arg"
done 
2

You can use shift builtin to discard one or more positional parameters, but you should check the number of parameters first:

if [ "$#" > 1 ]; then
  # Save first parameter value for using later
  arg1=$1
  shift
fi

Calling shift without any argument meaning shift 1.

Looping through all positional arguments:

for arg do
  : do something with "$arg"
done

In your case, you don't need the loop at all, since when cat can work with multiple files:

cat -- "$@"

Here's a test for calling shift when there's no positional arguments:

$ for shell in /bin/*sh /opt/schily/bin/[jbo]sh; do
  printf '[%s]\n' "$shell"
  "$shell" -c 'shift'
done

Output:

[/bin/ash]
/bin/ash: 1: shift: can't shift that many
[/bin/bash]
[/bin/csh]
shift: No more words.
[/bin/dash]
/bin/dash: 1: shift: can't shift that many
[/bin/ksh]
/bin/ksh: shift: (null): bad number
[/bin/lksh]
/bin/lksh: shift: nothing to shift
[/bin/mksh]
/bin/mksh: shift: nothing to shift
[/bin/pdksh]
/bin/pdksh: shift: nothing to shift
[/bin/posh]
/bin/posh: shift: nothing to shift
[/bin/sh]
/bin/sh: 1: shift: can't shift that many
[/bin/tcsh]
shift: No more words.
[/bin/zsh]
zsh:shift:1: shift count must be <= $#
[/opt/schily/bin/bsh]
shift: cannot shift.
[/opt/schily/bin/jsh]
/opt/schily/bin/jsh: cannot shift
[/opt/schily/bin/osh]
/opt/schily/bin/osh: cannot shift

Well, bash is silent with no positional arguments. Calling with placeholder in $0:

"$shell" -c 'shift' _

made csh variants and schily bsh to be silent, too. In case of error, zsh, csh variants and schily bsh won't quit the non-interactive script after reporting it.

1

You can use the shift command to shift the args, discarding the first one. Here is an example:

arg1=$1
shift
for arg in "$@"; do
  cat "$arg"
done
1
1

You can use array slicing ${@:2} :

$ foo () { echo "The args are ${@:2}" ;}
$ foo spam egg bar
The args are egg bar
1
  • 1
    Note: this is not available in all shells.
    – jordanm
    Sep 18, 2015 at 3:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .