List a count of similar filenames in a folder

Viewed 82

I have a folder which contains multiple files of a similar name (differentiated by a datetime in the filename)

I would like to be able to get a count of each file group/type in that folder.

i.e.

file1_25102019_111402.csv
file1_24102019_111502.csv
file1_23102019_121402.csv
file1_22102019_101402.csv

file2_25102019_161404.csv
file2_24102019_131205.csv
file2_23102019_121306.csv

I need to be able to return something like this;

file1 4
file2 3

Ideally the answer would be something like "count of files whose first x characters are ABCD"

The filenames can be anything. the date part in the example was just to demonstrate that the filenames begin with similar text but are distinghised by "something" further along in the name (in this case a date)

So I want to be able to Group them by the first X characters in the filename.

i.e. i want to be able to say, "give me counts of all files grouped by the first 4 characters, or the first 5 characters etc."

in SQL i'd do somthing like this

select   substr(object_name,1,5),
         count(*) 
from     all_objects 
group by substr(object_name,1,5)

Edited to show more examples;

File1weifwoeivnw
File15430293fjwnc
File15oiejfiwem
File2sidfsfe
File29fu09f4n
File29ewfoiwwf
File22sdiufsnvfvs

Pseudo Code:

Example 1:

ls count of first 4 characters

Output

File   7

Example 2:

ls count of first 5 characters

Output

File1    3
File2    4

Example 3

ls count of first 6 characters

Output

File1w    1
File15    2
File2s    1
File29    2
File22    1
1 Answers

If you want to extract the first 5 characters you can use

ls | cut -c1-5 | sort | uniq -c |awk '{ print $2,$1 }'

which prints for the first example from the question

file1 3
file2 3

If you want to have a different number of characters, change the cut command as necessary, e.g. cut -c1-6 for the first 6 characters.

If you want to separate the fields with a TAB character instead of a space, change the awk command to

awk -vOFS=\\t '{ print $2,$1 }'

This would result in

file1   3
file2   3

Other solutions that work with the first example that shows file names with a date and time string, but don't work with the additional example added later:

With your first example files, the command

ls | sed 's/_[0-9]\{8\}_[0-9]\{6\}/_*/' | sort | uniq -c

prints

      3 file1_*.csv
      3 file2_*.csv

Explanation:

  • The sed command replaces the sequence of a _, 8 digits, another _ and another 6 digits with _*.
    With your first example file names, you will get file1_*.csv or file2_*.csv 3 times each.
  • sort sorts the lines.
  • uniq -c counts the number of subsequent lines that are equal.

Or if you want to strip everything from the first _ up to the end, you can use

ls | sed 's/_.*//' | sort | uniq -c

which will print

      3 file1
      3 file2

You can add the awk command from the first solution to change the output format.

Related