Marc
Marc

Reputation: 640

pipe output of grep as an argument to a bash script

script.sh takes two files as arguments, and it calls a python script that opens them and does further processing on these files:

script.sh file1.txt file2.txt

I would like to remove all lines from file1.txt that start with #.

grep -v '^#' file1.txt

I tried the following but it fails :

script.sh $(grep -v '^#' file1.txt) file2.txt

How can I pipe the output of grep as the first file argument of script.sh?

Upvotes: 1

Views: 1633

Answers (1)

xdhmoore
xdhmoore

Reputation: 9876

script.sh <(grep -v '^#' file1.txt) file2.txt

Command substitution as you had it, $(), will insert the output from the grep command verbatim as arguments to script.sh. In contrast, to quote the bash man page:

Process substitution allows a process's input or output to be referred to using a filename. It takes the form of <(list) or >(list). The process list is run asynchronously, and its input or output appears as a filename. This filename is passed as an argument to the current command as the result of the expansion.

and

If the <(list) form is used, the file passed as an argument should be read to obtain the output of list.

So, my understanding is that when you use $(), the output of your grep command is substituted into the final statement with a result something like:

script.sh contents of file1 without comments \n oops newline etc file2.txt

But when you use <(), the grep command is run and the output goes into a named pipe or temporary file or some equivalent, and the name of that "file" is substituted into your statement, so you end up with something along the lines of

script.sh /dev/fd/temp_thing_containing_grep_results file2.txt

Upvotes: 3

Related Questions