14

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?

4
  • 1
    You have a list where? In an array variable? In a file? In your argument vector? Somewhere else? Commented Jul 23, 2014 at 19:00
  • Good question. I assumed @rhlee meant access the cmdline args, but maybe not. Commented Jul 23, 2014 at 19:02
  • A list of files in a directory, I created them using the seq command. Commented Jul 23, 2014 at 19:03
  • A list stored how? A list stored in a scalar variable? A list stored in a file? A list stored in an array? I still don't know what you mean by "list". Commented Jul 23, 2014 at 19:04

3 Answers 3

20

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[@]}"
Sign up to request clarification or add additional context in comments.

10 Comments

Yes, sorry about the confusion, by "list" I meant sequence of files. mycommand file{1..20} worked perfectly, thanks.
But then how does mycommand accept this list with other arguments?
@Akaisteph7, the argument vector is a flat list -- there's no support for nested structures at the underlying OS level, so everything is necessarily turned into just one list of strings.
I see. So essentially, a regular list in your examples would just be passed as a single, space-delimted string that can then be split up again from mycommand.
@Akaisteph7, ...as for this answer, to be 100% unambiguous: Absolutely none of the practices I showed generates a string with contents concatenated into a single space-separated argument; in every case, without exceptions, each array entry becomes a separate argument-list entry. (If by contrast someone used "${array[*]}" instead of "${array[@]}", then you'd get the first character of IFS -- by default a space -- separating the elements)
|
3

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.
Also, 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.
@CharlesDuffy Thanks for the downvote. I observe that Mark Reed (below), with 98.8k, suggests seq. Where's his downvote?
I hadn't noticed, but you're right; added one there too.
0

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

Yep, the curly bracket expansion works. It's a shame I can't mark multiple answers as the "correct one".
Well, that part of my answer was redundant with the one you accepted anyway. The only reason I answered at all was because you had added a comment about seq that hadn't been addressed yet. Not sure that's enough to leave this answer here..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.