Skip to content
Advertisement

How do I classify files in Linux server by their names?

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.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement