I am trying to print the first 10 lines of all files in a directory. Currently, I'm using:
ls -p | grep -v /
to remove all directories from the result of ls, and return just the files in the directory. When I then do:
ls -p | grep -v / | head
I would expect that the first ten lines from all the files would be printed, but it doesn't work.
Would anyone be able to help?
Your mistake is assuming that what a command receives from standard input is arguments. It is not.
When head receives data from a piped command, what it receives is a stream of data. The head
command is reading that data in the exact same way it would be reading from one file passed as an argument. Think of it this way (this is pseudo code, it will not work) :
PSEUDO_PIPELINE <= ls -p | grep -v / # Not valid shell syntax
head PSEUDO_PIPELINE # Not valid shell syntax
There actually is a (valid) way to express just that, and it is called process substitution :
head <(ls -p | grep -v /)
This will achieve the exact same (unwanted) result that you observed, but makes it more obvious that the command preceding the pipe is really a file, not an argument list.
Standard input (as well as output streams standard output and standard error) is something each command receives from its launching context. It is like a "hidden argument" if you want, and the process can interact with it (by reading from it until it reaches the end of the file, because it is a special file, but a file nonetheless).
Now you should understand why what you are getting is the first 10 10 lines of output of the preceding commands, and NOT the first 10 lines of each file listed.
You could achieve what you want with something like this :
find . -mindepth 1 -maxdepth 1 -type f -exec printf "\n%s ------\n" {} \; -exec head {} \;
This finds each file, and then prints a header/separator line, and the first lines of each file.