Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I'm running Mac OSX and trying to use the command line to find the number of files I have with the same name.

I tried to use the following command:

find ~ -type f -name "*" -print | basename | sort | uniq -d > duplicate_files

It doesn't work! When I do the following:

find ~ -type f -name "*" -print > duplicate_files

Then duplicate_files does contain the paths of all my files. So I think the issue is with basename - it doesn't accept standard input. I then tried the following:

basename $(find ~ -type f -name "*" -print) > duplicate_files

but again that doesn't seem to work. Search on the internet doesn't seem to yield much joy. Any thoughts most welcome.

share|improve this question

4 Answers 4

up vote 5 down vote accepted

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.)

share|improve this answer
    
Super thanks. This is exactly what I was trying to do ... very useful –  JohnB Mar 10 at 3:39

This seems to work for me on OSX:

find ~ -type f -exec basename -a {} + | sort | uniq -d
share|improve this answer
    
Yes - this is great thanks -- out of interest what does the + signify in the command? –  JohnB Mar 9 at 12:31
2  
Is this is useful please consider up-voting it. –  suspectus Mar 9 at 13:52
    
It is -- I cannot vote up beacuase i need 15 reputation :-( –  JohnB Mar 9 at 15:09
    
@StephaneChazelas: According to the man page for BSD basename, the executable can take multiple strings as arguments. I double checked on OSX, it works. –  rahmu Mar 10 at 11:31
1  
All right sorry, I stand corrected. I wasn't aware of that BSD extension. However, that still fails if there are exactly two files. You'd need to add the -a option to cover for that case as well. –  Stéphane Chazelas Mar 10 at 12:04

Alternatives (assumes no newline in file names):

find ~ -type f | awk -F/ '{print $NF}' | sort | uniq -d
share|improve this answer

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.

share|improve this answer
    
Thanks -- '-printf' doesn't work for OS X UNIX –  JohnB Mar 9 at 12:12
    
And when I try the second version I get basename: unknown primary or operator. Thanks for the tip on -name "*" –  JohnB Mar 9 at 12:19
    
That's strange. I can see -printf even in posix man page. About the error with second way, it's cause of typo in my answer. Fixed. Could you please try it one more time? –  rush Mar 9 at 12:23
    
Perfect -- works now. Thanks –  JohnB Mar 9 at 12:31
1  
Actually the best source would be man find in your console :) –  rush Mar 9 at 12:41

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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