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
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With