简体   繁体   中英

Which is more efficient : ls -l *ABC* vs ls -l | grep ABC

There are at least two ways of doing the same thing :) ls -l *ABC* and ls -l | grep ABC ls -l | grep ABC

But which one is more efficient? Are there others, more efficient?

They do two subtly different things.

ls -l *ABC* lists all entries in the current directory whose names contain ABC (and don't start with . ).

ls -l | grep ABC ls -l | grep ABC lists all entries in the current directory whose names don't start with . and then filters out all lines that don't contain ABC .

ls -l lists user and group names as well as file names, so if there happen to be files owned by a user or group whose name contains ABC , they'll be listed regardless of their names. Most group and user names don't contain uppercase letters, but that's not a firm requirement, and you'll want to do the same thing with other patterns like abc . If the pattern happens to be something contained in the word total , you'll match the first line of the output of ls -l .

More obscurely, file names can legally contain any characters other than / and the null character -- including newlines. Using such a name is a really bad idea, but such a file's name will be listed across two or more lines, and grep operates on lines.

The output of ls -l is intended to be human-readable. It's not really intended to be processed automatically.

ls -l *ABC* says what you mean more clearly and directly. Think about that before you consider performance. Unless your current directory is positively huge, any performance difference is likely to be swamped by the time it takes to print the output.

Having said all that, let's look at the likely performance issues.

In ls -l *ABC* , the *ABC* wildcard is handled by the shell; ls sees only a list of arguments. It requires the shell to scan the current directory and build a sorted list of file names matching the pattern. The ls command will then sort it again (and depending on your shell and locale settings, I'm not certain both sorts will yield the same order). Sorting might be a performance issue for very large directories. (Solution: Avoid making very large directories.) ls will be sorting fewer items than the shell does -- unless everything in the current directory matches *ABC* .

In ls -l | grep ABC ls -l | grep ABC , the ls command has to scan the current directory, sort it all, fetch metadata for everything, and then print it all, to have (probably) most of it filtered out by the separate grep process.

I don't know which is going to be faster. It likely depends on the contents of your current directory. But unless you're either working with huge directories or performing this operation many many times, the performance difference probably doesn't matter. If it does matter, measure it; that's the only way to know the difference in your environment .

Glob vs Grep.

The way ls -l *ABC* works is that the wildcards match the regex and populate an array of the file names matching that regex. Once that is done, ls simply lists out the files in long -l format.

ls -l | grep ABC ls -l | grep ABC uses linux pipes. The way pipes work is that it connects the STD_OUT of the left command to the STD_IN of the right command. Thus ls -l first generates a list of all the file names in long format, and then pipe passes this list to grep, which filters out the list based on its matching regex. Now, suppose this list is of a million files, it is unnecessary to pass this whole list when glob could populate it for you.

Thus ls -l | grep ABC ls -l | grep ABC would be much slower than ls -l *ABC*

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