If I have a list of files say file1 ... file20, how to I run a command that has the list of files as the arguments, e.g. myccommand file1 file2 ... file20?
3 Answers
If your list is in your argument vector -- that is to say, if you were started with:
./yourscript file1 file2 ...
then you'd run
mycommand "$@"
If your list is in an array:
mycommand "${my_list_of_files[@]}"
If your list is in a NUL-delimited file:
xargs -0 -- mycommand <file_with_argument_list
If your list is in a newline-delimited file (which you should never do for filenames, since filenames can legitimately contain newlines):
readarray -t filenames <file_with_argument_list
mycommand "${filenames[@]}"
If by "list", you just mean that you have a sequence of files:
mycommand file{1..20}
...or, to build an array of filenames with numeric components from a range more explicitly in cases where {1..20} doesn't work (such as when 20 is a variable):
max=20 # to demonstrate something you can't do with brace expansion
list=( )
for ((i=0; i<max; i++)); do
list+=( file"$i" )
done
mycommand "${list[@]}"
10 Comments
mycommand file{1..20} worked perfectly, thanks.mycommand accept this list with other arguments?mycommand."${array[*]}" instead of "${array[@]}", then you'd get the first character of IFS -- by default a space -- separating the elements)Look into the shift bash command (man bash). You can iterate, taking $1 each time.
for n in $(seq 1 $#); do
echo $1
shift
done
Call this file myshift.sh. Then
$ ./myshift.sh a b c
a
b
c
4 Comments
for loops already have a standard way of iterating over command-line arguments. This is just a non-standard way of writing for n; do echo "$n"; done.seq is nonstandard -- it's an external binary, not built into the shell, and not mandated by POSIX for operating systems to provide -- and you're paying extra time to start it up.seq. Where's his downvote?If you're generating a list of files with seq, you can just use command substitution to drop them into the command line:
mycommand $(seq ...)
although that will fail if the filenames so generated have any spaces (or tabs or newlines...) in them.
You can also use bash's curly-brace expansion to generate them instead of seq, for instance file{1..10} to generate file1 file2 file3 file4 file5 file6 file7 file8 file9 file10. This has the advantage of working even if the filename contains spaces in the common part, as long as you quote it properly (e.g. "file name"{1..10}).
2 Comments
seq that hadn't been addressed yet. Not sure that's enough to leave this answer here..
seqcommand.