How do I use the lines of a file as arguments of a command?

LinuxUnixShellCommand LineCommand Line-Arguments

Linux Problem Overview


Say, I have a file foo.txt specifying N arguments

arg1
arg2
...
argN

which I need to pass to the command my_command

How do I use the lines of a file as arguments of a command?

Linux Solutions


Solution 1 - Linux

If your shell is bash (amongst others), a shortcut for $(cat afile) is $(< afile), so you'd write:

mycommand "$(< file.txt)"

Documented in the bash man page in the 'Command Substitution' section.

Alterately, have your command read from stdin, so: mycommand < file.txt

Solution 2 - Linux

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

What was not mentioned, and I think is important to note, is that you must remember that the shell will break apart the contents of that file according to whitespace, giving each "word" it finds to your command as an argument. And while you may be able to enclose a command-line argument in quotes so that it can contain whitespace, escape sequences, etc., reading from the file will not do the same thing. For example, if your file contains:

a "b c" d

the arguments you will get are:

a
"b
c"
d

If you want to pull each line as an argument, use the while/read/do construct:

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

Solution 3 - Linux

command `< file`

will pass file contents to the command on stdin, but will strip newlines, meaning you couldn't iterate over each line individually. For that you could write a script with a 'for' loop:

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

Or (the multi-line variant):

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

Or (multi-line variant with $() instead of ``):

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

References:

  1. For loop syntax: https://www.cyberciti.biz/faq/bash-for-loop/

Solution 4 - Linux

You do that using backticks:

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

Solution 5 - Linux

If you want to do this in a robust way that works for every possible command line argument (values with spaces, values with newlines, values with literal quote characters, non-printable values, values with glob characters, etc), it gets a bit more interesting.


To write to a file, given an array of arguments:

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

...replace with "argument one", "argument two", etc. as appropriate.


To read from that file and use its contents (in bash, ksh93, or another recent shell with arrays):

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

To read from that file and use its contents (in a shell without arrays; note that this will overwrite your local command-line argument list, and is thus best done inside of a function, such that you're overwriting the function's arguments and not 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 sys.stdin.read().split("\0")][:-1]))
  '
}

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

Solution 6 - Linux

If all you need to do is to turn file arguments.txt with contents

arg1
arg2
argN

into my_command arg1 arg2 argN then you can simply use xargs:

xargs -a arguments.txt my_command

You can put additional static arguments in the xargs call, like xargs -a arguments.txt my_command staticArg which will call my_command staticArg arg1 arg2 argN

Solution 7 - Linux

Here's how I pass contents of a file as an argument to a command:

./foo --bar "$(cat ./bar.txt)"

Solution 8 - Linux

None of the answers seemed to work for me or were too complicated. Luckily, it's not complicated with xargs (Tested on Ubuntu 20.04).

This works with each arg on a separate line in the file as the OP mentions and was what I needed as well.

cat foo.txt | xargs my_command

One thing to note is that it doesn't seem to work with aliased commands.

The accepted answer works if the command accepts multiple args wrapped in a string. In my case using (Neo)Vim it does not and the args are all stuck together.

xargs does it properly and actually gives you separate arguments supplied to the command.

Solution 9 - Linux

I suggest using:

command $(echo $(tr '\n' ' ' < parameters.cfg))

Simply trim the end-line characters and replace them with spaces, and then push the resulting string as possible separate arguments with echo.

Solution 10 - Linux

In my bash shell the following worked like a charm:

cat input_file | xargs -I % sh -c 'command1 %; command2 %; command3 %;'

where input_file is

arg1
arg2
arg3

As evident, this allows you to execute multiple commands with each line from input_file, a nice little trick I learned here.

Solution 11 - Linux

After editing @Wesley Rice's answer a couple times, I decided my changes were just getting too big to continue changing his answer instead of writing my own. So, I decided I need to write my own!

Read each line of a file in and operate on it line-by-line like this:

#!/bin/bash
input="/path/to/txt/file"
while IFS= read -r line
do
  echo "$line"
done < "$input"

This comes directly from author Vivek Gite here: https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/. He gets the credit!

> Syntax: Read file line by line on a Bash Unix & Linux shell:
> 1. The syntax is as follows for bash, ksh, zsh, and all other shells to read a file line by line
> 2. while read -r line; do COMMAND; done < input.file
> 3. The -r option passed to read command prevents backslash escapes from being interpreted.
> 4. Add IFS= option before read command to prevent leading/trailing whitespace from being trimmed -
> 5. while IFS= read -r line; do COMMAND_on $line; done < input.file


And now to answer this now-closed question which I also had: https://stackoverflow.com/questions/22569497/is-it-possible-to-git-add-a-list-of-files-from-a-file - here's my answer:

Note that FILES_STAGED is a variable containing the absolute path to a file which contains a bunch of lines where each line is a relative path to a file I'd like to do git add on. This code snippet is about to become part of the "eRCaGuy_dotfiles/useful_scripts/sync_git_repo_to_build_machine.sh" file in this project, to enable easy syncing of files in development from one PC (ex: a computer I code on) to another (ex: a more powerful computer I build on): https://github.com/ElectricRCAircraftGuy/eRCaGuy_dotfiles.

while IFS= read -r line
do
    echo "  git add \"$line\""
    git add "$line" 
done < "$FILES_STAGED"

References:

  1. Where I copied my answer from: https://www.cyberciti.biz/faq/unix-howto-read-line-by-line-from-file/
  2. For loop syntax: https://www.cyberciti.biz/faq/bash-for-loop/
  1. How to read contents of file line-by-line and do git add on it: https://stackoverflow.com/questions/22569497/is-it-possible-to-git-add-a-list-of-files-from-a-file

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionYooView Question on Stackoverflow
Solution 1 - Linuxglenn jackmanView Answer on Stackoverflow
Solution 2 - LinuxWillView Answer on Stackoverflow
Solution 3 - LinuxWesley RiceView Answer on Stackoverflow
Solution 4 - LinuxTommy LacroixView Answer on Stackoverflow
Solution 5 - LinuxCharles DuffyView Answer on Stackoverflow
Solution 6 - LinuxCobra_FastView Answer on Stackoverflow
Solution 7 - LinuxchovyView Answer on Stackoverflow
Solution 8 - LinuxPhilTView Answer on Stackoverflow
Solution 9 - LinuxSylveView Answer on Stackoverflow
Solution 10 - LinuxcydonianView Answer on Stackoverflow
Solution 11 - LinuxGabriel StaplesView Answer on Stackoverflow