4

How can we concatenate results from stdout (or stderr) and a file into a final file.

For example

ls -a | grep text1

concatenate with file2.txt into a final result (not file2.txt), without storing grep text1 to something intermediate such as grep text1 > file1.txt

16
ls -a | grep text1 | cat file2.txt -

The - stands for standard input. Alternatively you may write

ls -a | grep text1 | cat - file2.txt

to have the output in different order.


Yet another possibility using process substitution:

cat <(ls -a | grep text1) file2.txt

or in different order:

cat file2.txt <(ls -a | grep text1)
  • That's interesting with -. But "standard input" ? Did you mean standard output ? How about stderr ? – Kenny Dec 23 '15 at 14:56
  • @Kenny - denotes standard input for cat. info cat states clearly "‘cat’ copies each FILE (‘-’ means standard input), or standard input if none are given, to standard output." – jimmij Dec 23 '15 at 15:01
  • But result of grep text1 would be in stdout, no ? – Kenny Dec 23 '15 at 15:18
  • @Kenny yes the result of grep will be in stdout of grep, but it is connected to stdin of cat via pipe. BTW, the overall output will be in standard output, a terminal by default. You can redirect it to a file (if you want) normally, i.e. by adding >file to the end of the command line. – jimmij Dec 23 '15 at 15:20
1

You can just append it on to the end of file2.txt by doing

ls -a | grep text1 >> file2.txt

Or if you want it in a different file

ls -a | grep text1 > output.txt
cat file2.txt >> output.txt

If you want the stderr instead of stdout

ls -a | grep text1 2>> output.txt

Note that this probably won't put anything in your file since ls -a is unlikely to output anything to stderr.

EDIT: If you want to pipe the results to another program instead of redirecting to a file you'll probably want to use named pipes.

mkfifo pipe1
cat pipe1 | next program &
ls -a | grep text1 >> pipe1
cat file2.txt >> pipe1
  • First solution does not work as asked. It appends to file2.txt thus changing it. – Marco Dec 23 '15 at 14:46
  • I look for something similar to your second proposition, using cat, but without the need of another file to hold result of the first grep. Imagine if I want to pipe the overall result into something else. – Kenny Dec 23 '15 at 14:47
  • @Marco They asked to concatenate the files, they never specified where the output should go. – David King Dec 23 '15 at 14:47
  • @Kenny See my edit – David King Dec 23 '15 at 14:49
  • @david-king Look at the end of the first line: into a final file – Marco Dec 23 '15 at 14:52
-1

You can do something like below

ls -a | grep text1 >> file2.txt 2>&1

2>&1 will redirect standard err to std output

  • it's not a god idea to use redirection in this kind of use – alexises Dec 23 '15 at 15:22
5

You can group commands together with {} or () and redirect their combined outputs:

{ 
  cat file1.txt
  echo "Now the ls/grep"
  ls -a |grep foobar
} > file2.txt

As a oneliner:

{ cat file1.txt; echo "Now the ls/grep"; ls -a |grep foobar; } >file2.txt 

That last ; is necessary.

0
ls -a | { grep text1; cat file2.txt; } >outfile

Here ls writes to grep which writes to a stdout it shares with the cat process that launches when its through filtering ls's output. When grep's cat writes a copy of file2.txt to the same shared stdout. Fewer pipes this way, usually.

... or ...

ls -a | sed -ne'$r file2.txt' -e'/text1/p' >outfile

Here sed stands in for grep and filters the input to output by printing only matches for a text1 regexp. When it reaches the $ last of ls's output, it schedules a read of file2.txt to output to occur after it has completely finished the current line cycle - and so as soon as it prints (or doesn't print) the last line of ls's output, it copies all of file2.txt to its stdout as well.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.