1

I am hunting for a certain regular expression within the filenames and am seeking to return the parent folders with their sizes in a unique fashion.

For example, here is the command that I expected to work:

find -E . -type f -regex '.*[fF][oO][oO].*' -maxdepth 2 | rev | cut -d'/' -f2- | rev | egrep -v '\.$' | uniq | xargs du -sh

This failed with a: xargs: unterminated quote thanks to varied quote marks within the filenames.

So I ended up utilizing find with -print0 and xargs with -0:

find -E . -type f -regex '.*[fF][oO][oO].*' -maxdepth 2 -print0 | rev | cut -d'/' -f2- | rev | egrep -v '\.$' | uniq | xargs -0 du -sh

Yet I ended up an error: du: Binary file (standard input) matches thanks to uniq apparently munging the output from find's -print0 formatting.

How would you suggest finding the parent folder size when searching for any file or folder under them that match? I repeat, I simply want to find the top level folder names with their accompanying sizes (du -sh) and no subfolder path or file information so that I ultimately end up with just a nice neat list of main folders that have matching criteria.

2

rev and egrep and uniq are all eating your zeros and seeing a single line. If you have GNU find and uniq you can simplify this a lot:

find ...tests... -printf '%h\0' | uniq -z | xargs -0 du -sh

GNU find's -printf option takes a format describing the output for each file. %h is the format for the path up to but not including the filename, and then \0 makes it zero-terminated. uniq -z tells it to use zeros for terminating each record - otherwise it'll only see a single line, and essentially act like cat. xargs can then continue as you had it.

It's conceivable that sort -z -u would be better than uniq to account for names out of order, although your maximum depth requirements mean that only . will appear more than once with anything in between. -mindepth 2 would avoid that as well.

If none of your filenames have zeros in them

1

The main complication in your example commands is getting the directory name. You can get this much easier, directly, with the -printf option of find. It has a format for writing out the directory only: %h. Using that should allow to simplify your command a lot.

To write out the directories only, use:

find ... -type f ... -printf '%h\n'

You can use that for \0-terminated lines too:

find ... -type f ... -printf '%h\0'


The second command in the question has an extra problem: It uses a pipe of commands that work on lines, but the input is not lines - there are no newlines, as you use \0 for line termination. To put it another way: the whole output is on one line.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.