4

I wonder if there is an easy command to list all files with the same names and number of that files? I would like to do it recursively and I do not mean concrete filename. I can imagine the output would look like this:

FILENAME   NUMBER
filename1    2
filename2    4
filename3    8 
Al Bundy
  • 181

2 Answers2

9

Using GNU find:

find /some/path -type f -printf '%f\n' | sort | uniq -c

Using POSIX find:

find /some/path -type f | sed 's~^.*/~~' | sort | uniq -c

This assumes your filenames don't contain newlines.

lcd047
  • 7,238
  • Alternative, with GNU tools and handling badly-behaved file names: find "$@" '!' -type d -print0 | xargs -0 basename -za | sort -z | uniq -cz | sort -nzr | tr '\0' '\n' - I've also shown how to include filenames that are symlinks or devices, and to sort the final output numerically. HTH. – Toby Speight Jul 17 '15 at 12:28
  • wow, that -c option to uniq renders my script useless. Thanks, that'll be useful in future. – FelixJN Jul 17 '15 at 12:31
  • Whats its O-complexity? Is it O(n*n)? @lcd047 – alper Apr 08 '18 at 12:28
  • 2
    @Alper The solution has the same complexity as your sort. Your question doesn't make much sense beyond that. :) – lcd047 Apr 08 '18 at 13:21
0

since you cannot have files with the same name in the same directory, I assumed you have them in different directories (e.g. folder1/file folder2/file folder1/otherfile folder2/otherfile )

for name in NAME1 NAME2 NAME3 ; do
    echo -n $name \ \ \ 
    ls */$name | wc -l 
done

If they just have the same prefix (i.e. picture1 picture2 frame1 frame2 ), then it is almost the same:

for name in NAME1 NAME2 NAME3 ; do
    echo -n $name \ \ \ 
    ls $name* | wc -l
done

For the headline just preceed the whole thing with

echo FILENAME \ \ \ \ NUMBER

(it's BASH script of course)


[Update following requests in comments:]

#!/bin/bash

  # alternative 1
  # put filenames sorted and without double entries into array fnames
  fnames=( $( find -type f -printf "%f\n" | sort | uniq ) )
  # alternative 2: including folder names:
  ## fnames=( $( find -printf "%f\n" | sort | uniq ) )

  # count each names number of appearances:

  for (( i=0 ; i<=${#fnames[@]}-1 ; i++ )) ; do
    # alternative 1: files only
    number=$( find -type f -wholename "*/${fnames[$i]}" -printf "%f\n" | wc -l )
    # alternative 2: files and folders with same name
    ## number=$( find -wholename "*/${fnames[$i]}" -printf "%f\n" | wc -l )

    echo -e ${fnames[$i]} \ \ \ $number

  done
FelixJN
  • 13,566