What's the difference between-print0 in linux find and-0 in xargs?
Editor to share with you linux find-print0 and xargs-0 what is the difference, I believe that most people do not know much about it, so share this article for your reference, I hope you will learn a lot after reading this article, let's go to know it!
By default, each filename output by find is followed by a newline character ('n'), so the output of find we see is line by line:
The code is as follows:
[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, if I want to delete all .log files, I can use it with xargs:
The code is as follows:
[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'
Well, yes, find+xargs is really powerful. However:
The code is as follows:
[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.Logistic: No such file or directory
Rm: cannot remove `. / file': No such file or directory
Rm: cannot remove `2.logboxes: No such file or directory
The reason is very simple. Xargs splits records with white space characters (space, TAB, newline character) by default, so the file name. / file 1.log is interpreted as two records. / file and 1.log, unfortunately rm can not find these two files.
To solve this problem, the smart guy came up with a way to have find print out a NULL character ('') instead of a newline character after printing a file name, and then tell xargs to also use the NULL character as the record delimiter. This is the origin of find's-print0 and xargs's-0.
The code is as follows:
[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
0123456789ABCDEF | 0123456789ABCDEF |
-+-|
00000000: 2e 2f 66 69 6c 65 20 31 2e 6c 6f 67 00 2e 2f 66 |. / file 1.log../f |
00000010: 69 6c 65 20 32 2e 6c 6f 67 00 | 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 as delimiters? This is also easy to understand: most programming languages use''as the end of a string, and the pathname of a file cannot contain the''character.
Other find and xargs instances I have collected:
Delete files 10 days ago that end in html, including files with spaces:
The code is as follows:
Find / usr/local/backups-name "* .html"-mtime + 10-print0 | xargs-0 rm-rfvfind / usr/local/backups-mtime + 10-name "* .html"-exec rm-rf {}
Differences between find-print and-print0:
-print adds a carriage return newline character after each output, while-print0 does not.
The files in the current directory 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: output columns can be numbered, similar to cat-n, but blank lines are not numbered
The following functions are the same as above, 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'Unix AAA BBG'
Xargs combined with grep:
Find. -name'* .txt'- type f-print0 | xargs-0 grep-n 'aaa' # "- n" output line number
The above is all the content of this article entitled "what's the difference between linux find-print0 and-0 in xargs". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!