Why does “find . -name *.txt | xargs du -hc” give multiple totals?

前提是你 提交于 2019-11-30 09:45:06

How about using the --files0-from option to du? You'd have to generate the null-terminated file output appropriately:

find . -name "*txt" -exec echo -n -e {}"\0" \; | du -hc --files0-from=-

works correctly on my system.

find . -print0 -iname '*.txt' | du --files0-from=-

and if you want to have several different extensions to search for it's best to do:

find . -type f -print0 | grep -azZEi '\.(te?xt|rtf|docx?|wps)$' | du --files0-from=-

The xargs program breaks things up into batches, to account for the limits due to the maximum length of a unix command line. It's still more efficient than running your subcommand one at a time but, for a long list of inputs, it will run the command enough times that each "run" is short enough that it won't cause issues.

Because of this, you're likely seeing one output line per "batch" that xargs needs to run.

Because you may find it useful/interesting, the man page can be found online here: http://unixhelp.ed.ac.uk/CGI/man-cgi?xargs


One other thing to note (and this may be a typo in your post or my misunderstanding) is that you have the "*.txt" unescaped/quoted. Ie, you have

find . -name *.txt | xargs du -hc

where you probably want

find . -name \*.txt | xargs du -hc

The difference being that the command line may be expanding the * into the list of filenames that match... rather than passing the * into find, which will use it as a pattern.

Another simple solution:

find . -name *.txt -print0 | xargs -0 du -hc

One alternate solution is to use bash for loop:

for i in `find . -name '*.txt'`; do du -hc $i | grep -v 'total'; done

This is good for when you need more control of what happens in the loop.

xargs busts its input into reasonable-sized chunks - what you're seeing are totals for each of those chunks. Check the man page for xargs on ways to configure its handling of input.

One alternate solution is to use awk:

find . -name "*.txt" -exec ls -lt {} \; | awk -F " " 'BEGIN { sum=0 } { sum+=$5 } END { print sum }'
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!