This article requires a general understanding of the use of find and Xargs. If you don’t, you can learn better by coming back and learning along with the article.

The find command is used to search for files that meet the specified conditions. The search result can be sent to the subsequent command in the form of parameters in either of the following ways.

The two methods are

  • Use the “-exec” parameter that comes with find.
  • By the | (pipe) is passed to the xargs.

1. The target

We will use a combination of find and xargs to search the current folder for the number of lines of code with the “class” string in all Python files

2. Implement

We can give four different implementations, and we’ll explain what the differences are between them later

# -exec \;
find . -name "*.py" -type f -exec grep 'class' {} \; | wc -l
14029

# -exec \+
find . -name "*.py" -type f -exec grep 'class' {} \+ | wc -l
14029

# find | xargs -n1
find . -name "*.py" -type f | xargs -n1 grep 'class' | wc -l
14029

# find | xargs
find . -name "*.py" -type f | xargs grep  'class' | wc -l
14029
Copy the code

The execution results of the four commands are the same, but the waiting time of different commands varies greatly. How can I obtain the exact execution time of the command? You can use the Linux time command

# -exec \; time (find . -name "*.py" -type f -exec grep 'class' {} \; | wc -l) 0.12 0.57 s system s user 9% CPU total 7.140 # - exec \ + time (. Find -name "* x" -type f - exec grep 'class' {} \ | + wc -l) 0.06 s user s system 0.33 35% CPU 1.106 total # find | xargs - n1 time (. Find -name "* x" -type f | xargs - n1 Grep 'class' | wc -l) 0.15 s user s system 0.92 14% CPU 7.472 total # find | xargs time (. Find -name "* x" -type f | Xargs grep 'class' | wc -l) 0.06 0.42 s user s system CPU 1.066 total 45%Copy the code

Time is used to analyze the execution time of each command, including user mode time and kernel mode time. The first result is used as an example

0.12s user 0.57s system 9% cpu 7.140 total
Copy the code

The CPU usage during the execution of the command is 9%. The total execution time is 7.140 seconds. = Total time? In fact, the command process is not in the running state all the time. When the process is blocked, it will not be counted to the user state or the system state, but it will still be counted to the total time, which is why the CPU usage is only 9%.

3. Explain

3.1   find \;

find . [args] -exec [cmd] {} \;
Copy the code

{} represents the result set to be searched.

\; The CMD command will be executed as many times as the number of files found.

For our given implementation, this command is equivalent to 14,029 executions

grep 'class' filename
Copy the code

The find \ + 3.2

find . [args] -exec [cmd] {} \+
Copy the code

As above {} represents the result set searched,

\+ means that all elements in the search result set are passed to the command after exec at once. That is, no matter how many files find, the command is passed to CMD at once, which means that CMD is executed only once

For our implementation, this command is executed once

grep 'class' filename1  filename2 filename3 ...
Copy the code

3.3 xargs – n1

Xargs is used to pass standard input into command-line arguments to CMD

It’s a little bit abstract, but let’s do it with an example

cat ~/.bash_history | echo
Copy the code

Here we print out. Bash_history content through its | passed to echo, echo will not have any output

But if we use XARgs

cat ~/.bash_history | xargs echo
Copy the code

Ehco will then print the contents of.bash_history

find .[args] | xargs -n1 [cmd]
Copy the code

-n1 indicates that the arguments in the pipe are passed to CMD one by one for execution, so it is equivalent to:

find . -exec [cmd] {} \;
Copy the code

3.4    xargs 

find .[args] | xargs [cmd]
Copy the code

If xargs does not specify the -n argument, xargs defaults to -n5000, which is a group of 5000 arguments passed to subsequent CMD execution, which in most cases is equivalent to:

find . -exec [cmd] {} +;
Copy the code

In our implementation, it’s equivalent to

grep 'class' file1 file2 ... file5000grep 'class' file5001 file5002 ... 
Copy the code

4 summarizes

So in daily work if we need to use the find | xargs or find – the exec, Preferred to use the find – the exec {} \ + or find | xargs, if behind the CMD only support when passing a parameter and then use the find – the exec {} \; Or find | xargs – n1.

If you have additional comments on the use of find and Xrags, or have a different opinion on one of the points in this article, feel free to comment in the comments section at 😊.