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 Answers 2

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .