Coder Perfect

How do I utilize lines from a file as command arguments?


Let’s say I have a file foo.txt with N parameters.


which I must provide to the command my command

How do I utilize lines from a file as command arguments?

Asked by Yoo

Solution #1

If you’re using bash (among other shells), $(afile) is a shortcut for $(cat afile), therefore you’d type:

mycommand "$(< file.txt)"

The ‘Command Substitution’ portion of the bash man page documents this.

Alternatively, read your command from stdin, like follows: file.txt file.txt file.txt file.txt file.txt

Answered by glenn jackman

Solution #2

As already mentioned, you can use the backticks or $(cat filename).

What was not mentioned, but I believe is crucial to understand, is that the shell will break up the contents of that file according to whitespace, passing each “word” it finds to your command as an argument. While enclosing a command-line argument in quotes allows it to contain whitespace, escape sequences, and other special characters, reading from a file does not. For instance, if your file contains the following:

a "b c" d

The following are some of the arguments you will encounter:


Use the while/read/do construct if you want to pull each line as an argument:

while read i ; do command_name $i ; done < filename

Answered by Will

Solution #3

command `< file`

will provide the contents of the file to the command on stdin, but will clip newlines, so you won’t be able to iterate over each line separately. You could do this by writing a script with a ‘for’ loop:

for line in `cat input_file`; do some_command "$line"; done

Alternatively (the multi-line variant):

for line in `cat input_file`
    some_command "$line"

Alternatively (multi-line variation using $() instead of “):

for line in $(cat input_file)
    some_command "$line"

Answered by Wesley Rice

Solution #4

Backticks are used to do this:

echo World > file.txt
echo Hello `cat file.txt`

Answered by Tommy Lacroix

Solution #5

It gets a little more complex if you want to do it in a way that works for all potential command line arguments (values with spaces, values with newlines, values with literal quote characters, non-printable values, values with glob characters, and so on).

Given an array of arguments, write to a file:

printf '%s\0' "${arguments[@]}" >file

…replace as needed with “argument one,” “argument two,” and so on.

To read from and use the contents of that file with bash, ksh93, or another recent shell with arrays, type:

declare -a args=()
while IFS='' read -r -d '' item; do
  args+=( "$item" )
done <file
run_your_command "${args[@]}"

To read from that file and utilize its contents (in a shell without arrays; note that this will rewrite your local command-line argument list, therefore it’s preferable to do it inside of a function, so you’re overwriting the function’s arguments rather than the global list):

set --
while IFS='' read -r -d '' item; do
  set -- "$@" "$item"
done <file
run_your_command "$@"

Note that -d (allowing a different end-of-line delimiter to be used) is a non-POSIX extension, and a shell without arrays may also not support it. Should that be the case, you may need to use a non-shell language to transform the NUL-delimited content into an eval-safe form:

quoted_list() {
  ## Works with either Python 2.x or 3.x
  python -c '
import sys, pipes, shlex
quote = pipes.quote if hasattr(pipes, "quote") else shlex.quote
print(" ".join([quote(s) for s in"\0")][:-1]))

eval "set -- $(quoted_list <file)"
run_your_command "$@"

Answered by Charles Duffy

Post is based on