By default, the Find command outputs a file name each, followed by a newline character (' n '), so the output of find is one line:
[bash-4.1.5] Ls-l
Total 0
-rw-r--r--1 root root 0 2010-08-02 18:09 File1.log
-rw-r--r--1 root root 0 2010-08-02 18:09 file2.log
[bash-4.1.5] find-name ' *.log '
./file2.log
./file1.log
For example, use the Find command to delete all the. log files, which can be used in conjunction with Xargs:
[bash-4.1.5] find-name ' *.log '
./file2.log
./file1.log
[bash-4.1.5] find-name ' *.log ' | Xargs RM
[bash-4.1.5] find-name ' *.log '
The find command combined with Xargs is really powerful. However:
[bash-4.1.5] Ls-l
Total 0
-rw-r--r--1 root root 0 2010-08-02 18:12 file 1.log
-rw-r--r--1 root root 0 2010-08-02 18:12 file 2.log
[bash-4.1.5] find-name ' *.log '
./file 1.log
./file 2.log
[bash-4.1.5] find-name ' *.log ' | Xargs RM
Rm:cannot remove './file ': No such file or directory
Rm:cannot remove ' 1.log ': No such file or directory
Rm:cannot remove './file ': No such file or directory
Rm:cannot remove ' 2.log ': No such file or directory
The reason is very simple, xargs by default is a blank character (space, TAB, line break) to split the record, so the file name./file 1.log is interpreted as two records./file and 1.log, unfortunately RM cannot find these two files.
To solve this problem, let the find command print out a file name and then output a null character ("') instead of a newline character, and then tell Xargs to use the null character as the delimiter for the record. This is the origin of the-print0 and Xargs 0 of find.
[bash-4.1.5] Ls-l
Total 0
-rw-r--r--1 root root 0 2010-08-02 18:12 file 1.log
-rw-r--r--1 root root 0 2010-08-02 18:12 file 2.log
[bash-4.1.5] find-name ' *.log '-print0 | hd
0 1 2 3 4 5 6 7 8 9 A B C D E F |0123456789abcdef|
--------+--+--+--+--+---+--+--+--+---+--+--+--+---+--+--+--+--+----------------|
00000000:2E 2f, 6c, 2e 6c 6f, 2e, 2f 66 |. /file 1.log.. /f|
00000010:69 6c 2e 6c 6f |ile 2.log |
[bash-4.1.5] find-name ' *.log '-print0 | xargs-0 RM
[bash-4.1.5] find-name ' *.log '
You may have to ask, why choose "instead of other characters to do the delimiter?" This is also easy to understand: in the General programming language, "is used as the end of the string, the path name of the file cannot contain the ' character."
Share some examples of Find commands with Xargs :
Delete files that end in HTML 10 days ago, including files with spaces:
Find/usr/local/backups-name "*.html"-mtime +10-print0 |xargs-0 rm-rfvfind/usr/local/backups-mtime +10-name "*.htm L "-exec rm-rf {};
The difference between Find-print and-print0:
-print adds a carriage return newline character after each output, while-print0 does not.
In the current directory, the files are sorted from large to small (including hidden files), and the file name is not "." :
Find. -maxdepth 1! -name "."-print0 | xargs-0 Du-b | Sort-nr | head-10 | nl
NL: You can add numbers to output columns, similar to cat-n, but empty lines are not numbered
The following features are the same, but do not include hidden files:
for file in *; Do du-b "$file"; Done|sort-nr|head-10|nlx
args combined with sed replacement:
Find. -name "*.txt"-print0 | xargs-0 sed-i ' s/aaa/bbb/g '
Xargs combined with grep:
Find. -name ' *.txt '-type f-print0 |xargs-0 grep-n ' aaa ' # "-n" output line number
[Zz]linux Find command in the use of-print0 and Xargs-0