0

I want to merge all files into one. Here, the last argument is the destination file name. I want to take last argument and then in loop stop before last arguments.

Here code is given that I want to implement:

echo "No. of Argument : $#"
for i in $* - 1
do
   echo $i
   cat $i >> last argument(file)
done

How to achieve that?

2
  • 1
    Note that it would be a lot easier if the target file was listed first and the source files afterwards. You'd have: target="$1"; shift; cat "$@" > "$target" and it would not rely on Bash. The GNU commands mv and cp have been modified to support an option -t destination to specify a destination directory, which is similar to what I propose. Commented Nov 3, 2014 at 1:38
  • 2
    yeah it is one of the good logic... thanks
    – LoveToCode
    Commented Nov 4, 2014 at 3:44

2 Answers 2

3

Using bash:

fname=${!#}
for a in "${@:1:$# - 1}"
do
    echo "$a"
    cat "$a" >>"$fname"
done

In bash, the last argument to a script is ${!#}. So, that is where we get the file name.

bash also allows selecting elements from an array. To start with a simple example, observe:

$ set -- a b c d e f
$ echo "${@}"
a b c d e f
$  echo "${@:2:4}"
b c d e

In our case, we want to select elements from the first to the second to last. The first is number 1. The last is number $#. We want to select all but the last. WE thus want $# - 1 elements of the array. Therefore, to select the arguments from the first to the second to last, we use:

${@:1:$# - 1}
0
3

A POSIX-compliant method:

eval last_arg=\$$#
while [ $# -ne 1 ]; do
    echo "$1"
    cat "$1" >> "$last_arg"
    shift
done

Here, eval is safe, because you are only expanding a read-only parameter in the string that eval will execute. If you don't want to unset the positional parameters via shift, you can iterate over them, using a counter to break out of the loop early.

eval last_arg=\$$#
i=1
for arg in "$@"; do
    echo "$arg"
    cat "$arg" >> "$last_arg"
    i=$((i+1))
    if [ "$i" = "$#" ]; then
        break
    fi
 done
0

Not the answer you're looking for? Browse other questions tagged or ask your own question.