Use basename to parse a list of paths held in a file

basename operates on its command line argument, it doesn't read from standard input.

You don't need to call the basename utility, and you'd better not: all it would do is strip off the part before the last /, and it would be slow to call an external command for each entry, you can use a text processing utility instead.

find ~ -type f | sed 's!.*/!!' | sort | uniq -d

It may be more useful to keep track of the location of the files. Sorting by name makes it easier to locate duplicates, but sort doesn't have an option to use the last field. What you can do is copy the last /-separated field to the beginning, then sort, and then use a bit of ad hoc awk processing to extract and present the duplicates.

find ~ -type f |
sed 's!.*/\(.*\)!\1/&!' |   # copy the last field to the beginning
sort -t/ -k1,1 |
cut -d/ -f2- |   # remove the extra first field (could be combined with awk below)
awk -F / '{
    if ($NF == name) {
        if (previous != "") {print previous; previous = ""}
        print
    } else {
        previous = $0
        name = $NF
    }
'

(Note that I assume that none of your file names contain newline characters.)


Why not to use builtin find features to output just filename:

find ~ -type f -printf '%f\n' | sort | uniq -c

(assumes GNU find) or at least something like this:

find ~ -exec basename {} \; | sort | uniq -c

basename can't read via pipe or process multiple files at once.

ps. There is no need to specify -name '*' if you want to list all the files. This is a default option.


This seems to work for me on OSX:

find ~ -type f -exec basename -a {} + | sort | uniq -d