2

I want to write part of the results of a stream to a file, but I want the entire contents of the stream printed to the console. Is there some command that would help with this?

Minimal example:

Say I had a file foo.txt with contents:

bat
dude
rude

And I wanted to write all lines in that file which contain the letter 'a' to bar.txt. I could write

cat foo.txt | grep 'a' > bar.txt

Which would result in bar.txt containing bat. But that wouldn't give me the console output that I want.

Instead I would prefer something like:

cat foo.txt | output-stdin-to-console-and-pass-to-stdout | grep 'a' > bar.txt

Which would not only write bat to bar.txt but also write the following to the console:

bat
dude
rude

Is there any command I can run to do that?

Zain R
  • 181
  • 2
  • 9
  • [How to redirect output to a file and stdout](https://stackoverflow.com/q/418896/995714), [How can I both pipe and display output in Windows' command line?](https://superuser.com/q/767680/241386), [How to show output on terminal and save to a file at the same time?](https://superuser.com/q/159059/241386) – phuclv Oct 24 '18 at 04:45

2 Answers2

1

Explicit examples with tee:

  • tee writing to the tty

    < foo.txt tee /dev/tty | grep 'a' > bar.txt
    

    This is portable, works in sh.

  • tee writing to process substitution, its standard output goes to the console:

    < foo.txt tee >(grep 'a' > bar.txt)
    

    This is not portable, works in Bash and few other shells.

Note I got rid of the cat command (useless use of cat).

Kamil Maciorowski
  • 69,815
  • 22
  • 136
  • 202
  • I love this because its a chance for me to learn redirection better. Here's an comparison of two lines that makes it clear for me (`echo hello > file; echo world >> file`): `cat file | tee /dev/tty | grep hello` and `< file tee /dev/tty | grep hello` ..both output a tee of "hello" and "world", and then the piped the found line of "hello". Also `tee /dev/tty < file | grep hello` does the same. – alchemy Mar 18 '23 at 23:44
0

You could simply use this:

cat foo.txt && cat foo.txt | grep 'a' > bar.txt

Otherwise, a one liner is possible using tee

From https://www.geeksforgeeks.org/tee-command-linux-example/

tee command reads the standard input and writes it to both the standard output and one or more files. The command is named after the T-splitter used in plumbing. It basically breaks the output of a program so that it can be both displayed and saved in a file. It does both the tasks simultaneously, copies the result into the specified files or variables and also display the result.

post irony
  • 51
  • 4