简体   繁体   中英

head doesn't work when piped a result from ls | grep

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?

To find all the files which are not directories in the current directory:

find . -mindepth 1 -maxdepth 1 -type f

Then you can use -exec to run a command on each of those files.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM