1

I thought this would be easy and there are a lot of somewhat close threads on the internet, but nothing quite right.

I want to use fd (simple find command) to display just file name and file size (preferably in mb, or formatted more readable than bytes), of the search results.

The closest I have come is using:

fd '2023' -x stat --format='%n : $s'

This seems to work okay for files, but doesn't work for directories.

E.g.

fd --type d '2023' -x stat

I tried playing pipes | and tee and xargs. But being a novice, I didn't have any luck.

Any ideas how I can display the output for files and folders and how can I format the bytes to the appropriate units?

Thanks

1 Answer 1

1

Rather than the size of the directory files¹, it looks like you want the cumulative size or maybe disk usage of those directories and all the the files that can be found through their traversal.

Then you likely want:

fdfind --type d 2023 -X du -sh --

(here using the fdfind name of that command as found on Debian and derivatives as there's a pre-existing fd command which is for something completely unrelated; replace with fd if that's how it's called on your system).

That's for disk usage; add a --apparent-size option to du for size instead.

Bear in mind that du does some deduplication and counts the disk usage of a file only once if it's found (via any of its hardlinks or via the same paths) in more than one directory. For instance, if there's a 2023/2023 directory, you'll see 0 for the disk usage of the subdirectory, because it and all the files within have already been accounted for in the report for the upper 2023 directory.

You can disable that deduplication with --count-links.

You may also want to pass a --prune option to fdfind to stop looking for more files in the directories that match.

Note the -- which you need to separate options from files (without it, you'd run into issues for a file called -2023, or --files0-from=2023/etc/shadow for instance (leading to a potential information disclosure vulnerability). Same would apply for stat or most commands.

And note the -X instead of -x for du to be passed as many file paths as possible instead of being run once in a new process for each file. Note that because du may end up being called more than once if there's a large list of matching files, that could make the deduplication mentioned above unreliable. A better way to pass the file list to du would be via its stdin using the --files0-from option. Then you could even add the -c option to get a cumulative total line at the end:

fdfind --type d --print0 2023 | du --files0-from=- -sch --

-h (--human-readable), --count-links, --files0-from and --apparent-size are all non-standard extensions of the GNU implementation of du. -h is commonly found in other implementations these days, the other ones (including the --human-readable long form of -h) more rarely so.


¹ think of a directory as a phone directory for instance. On many file systems, that's a bit like a CSV file that contains a list of file names in one column and where to find them (the inode number) on disk in another (and sometimes a third column to indicate the type of the file). And like any file that directory/csv file has a size and a disk usage of its own and that's the one gstat -c %s or gfind -printf %s or ls -l report.

4
  • Fantastic explanation, very well written. I learnt a great deal, thanks. So -print0 2023 will convert the string 2023 to file name stdout and --files0-from=- takes this. I find it really weird that you can just throw double dash -- on the end of the command and magically files beginning with dash work.
    – 1toneboy
    Commented Jun 4, 2023 at 13:23
  • 1
    A -- argument encountered while processing options means "end of options", that's recognised by all commands that parse their options the standard way or the GNU way. du -h -s gets you the total disk usage of the current working directory without details of sub-directories, du -h -- -s gets you the disk usage of file file called -s (with details of subdirectories if that file is a directory). Commented Jun 4, 2023 at 13:32
  • Thanks again Stéphane, ah, so not just applicable to find/fd. I guess what I find strange is that for example "fdfind --type d --print0 2023 | du --files0-from=- -sch --" the double dash is at the end, but it is applicable to 2023, indicating that there are no options in the string 2023, which is before the pipe. Not after the double dash. Hence what I meant by it magically knows. Or, is it that when you use a double dash you need to use two dashes before an option, such as when we wrote --type
    – 1toneboy
    Commented Jun 5, 2023 at 9:16
  • I forgot, we wrote -X whilst still using --, so I wish to retract the section above where I said "Or, is it that when you use a double dash you need to use two dashes before an option, such as when we wrote --type" because that is clearly not an explanation. However, the comment edit time expired so I couldn't edit it.
    – 1toneboy
    Commented Jun 5, 2023 at 9:28

You must log in to answer this question.

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