Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why not pipe list of file names into cat?

Tags:

unix

pipe

What is the design rationale that cat doesn't take list of file names from pipe input? Why did the designers choose that the following does not work?

ls *.txt | cat

Instead of this, they chose that we need to pass the file names as argument to cat as:

ls *.txt | xargs cat
like image 522
Mert Nuhoglu Avatar asked Oct 18 '14 19:10

Mert Nuhoglu


People also ask

What is the difference between cat file and cat file?

There is no difference from a user point of view. These commands do the same thing. Technically the difference is in what program opens the file: the cat program or the shell that runs it.

How do you cat a file with a space in the name?

Another way to deal with spaces and special characters in a file name is to escape the characters. You put a backslash ( \ ) in front of the special character or space. This makes the bash shell treat the special character like a normal (literal) character.

How do I add a file to a cat?

To create a new file, use the cat command followed by the redirection operator ( > ) and the name of the file you want to create. Press Enter , type the text and once you are done, press the CRTL+D to save the file.


2 Answers

To make it short, cat is a command, like echo or cp, and few others, which cannot convert pipe redirected input stream into arguments.

So, xargs, is used, to pass the input stream as an argument to the command.

More details here: http://en.wikipedia.org/wiki/Xargs

As a former unix SA, and now, Python developer, I believe I could compare xargs, to StringIO/CStringIO, in Python, as it kind of helps the same way.

When it comes to your question: Why didn't they allow stream input? Here is what I think

Nobody but them could answer this.

I believe, however, than cat is meant to print to stdout the content of a file, while the command echo, was meant to print to stdout the content of a string.

Each of these commands, had a specific role, when created.

like image 137
DevLounge Avatar answered Nov 11 '22 19:11

DevLounge


When you say ls *.txt | cat doesn't work, you should say that doesn't work as you expect. In fact, that works in the way it was thought to work.

From man:

cat - Concatenate FILE(s), or standard input, to standard output

Suppose the next output:

$ ls *.txt
file1.txt
file2.txt

... the input to cat will be:

file1.txt
file2.txt

...and that's exactly what cat output in the standard output

In some shells, it's equivalent to:

cat <(ls *.txt)

or

ls *.txt > tmpfile; cat tmpfile

So, cat is really working as their designers expected to do so.


On the other hand, what you are expecting is that cat interprets its input as a set of filenames to read and concatenate their content, but when you pipe to cat, that input works as a lonely file.

like image 26
whoan Avatar answered Nov 11 '22 17:11

whoan