How can use the ls command and options to list the repetitious filenames that are in different directories?
Advertisement
Answer
You can’t use a single, basic ls
command to do this. You’d have to use a combination of other POSIX/Unix/GNU utilities. For example, to find the duplicate filenames first:
find . -type f -exec basename "{}" ; | sort | uniq -d > dupes
This means find
all the files (-type f
) through the entire directory hierarchy in the current directory (.
), and execute (-exec
) the command basename
(which strips the directory portion) on the found file ({}
), end of command (;
). These files then sort and print out duplicate lines (uniq -d
). The result goes in the file dupes
. Now you have the filenames that are duplicated, but you don’t know what directory they are in. Use find
again to find them. Using bash
as your shell:
while read filename; do find . -name "$filename" -print; done < dupes
This means loop through (while
) all contents of file dupes
and read
into the variable filename
each line. For each line, execute find
again and search for the specific -name
of the $filename
and print it out (-print
, but it’s implicit so this is redundant).
Truth be told you can combine these without using an intermediate file:
find . -type f -exec basename "{}" ; | sort | uniq -d | while read filename; do find . -name "$filename" -print; done
If you’re not familiar with it, the |
operator means, execute the following command using the output of the previous command as the input to the following command. Example:
eje@EEWANCO-PC:~$ mkdir test eje@EEWANCO-PC:~$ cd test eje@EEWANCO-PC:~/test$ mkdir 1 2 3 4 5 eje@EEWANCO-PC:~/test$ mkdir 1/2 2/3 eje@EEWANCO-PC:~/test$ touch 1/0000 2/1111 3/2222 4/2222 5/0000 1/2/1111 2/3/4444 eje@EEWANCO-PC:~/test$ find . -type f -exec basename "{}" ; | sort | uniq -d | while read filename; do find . -name "$filename" -print; done ./1/0000 ./5/0000 ./1/2/1111 ./2/1111 ./3/2222 ./4/2222
Disclaimer: The requirement stated that the filenames were all numbers. While I have tried to design the code to handle filenames with spaces (and in tests on my system, it works), the code may break when it encounters special characters, newlines, nuls, or other unusual situations. Please note that the -exec
parameter has special security considerations and should not be used by root over arbitrary user files. The simplified example provided is intended for illustrative and didactic purposes only. Please consult your man
pages and relevant CERT advisories for full security implications.