Using Raku (formerly known as Perl_6)
raku -e '.say for dir.split("_")[2,5,8...*].Bag.pairs.sort;'
Sample Input (current directory listing):
my_file_A_a.txt
my_file_A_d.txt
my_file_A_f.txt
my_file_A_t.txt
my_file_B_r.txt
my_file_B_x.txt
my_file_C_f.txt
my_file_D_f.txt
my_file_D_g.txt
my_file_E_r.txt
Sample Output:
A => 4
B => 2
C => 1
D => 2
E => 1
As a brief explanation, the current directory dir()
listing is obtained and split on _
underscore. [File names are assumed not to start/end with _
underscore]. The elements obtained are thus:
raku -e 'dir.split("_").raku.say;'
("my", "file", "A", "a.txt my", "file", "A", "d.txt my", "file", "A", "f.txt my", "file", "A", "t.txt my", "file", "B", "r.txt my", "file", "B", "x.txt my", "file", "C", "f.txt my", "file", "D", "f.txt my", "file", "D", "g.txt my", "file", "E", "r.txt").Seq
After that, Raku has a fairly robust mechanism for generating/understanding sequences: simply typing in [2,5,8...*]
lets you pull out the letters A,B,C,D,E
(every third element, numbering starts from 0
). Then Bag
, pairs
, and sort
.
(If you're sure you have no
blank spaces in your file names, you could add a second call to split(" ")
after the first one. Then the elements you would pull out would be [2,6,10...*]
).
NOTE 1: If you have extraneous file names that don't fit the pattern listed by the OP (and are mucking up your counts), then you could change the dir
call to something like dir(test => / [ <-[_]>+ _ ] ** 3 /)
which subsets filenames on a regex where one-or-more non-underscores are followed by an underscore, repeated three times.
NOTE 2: If you want two columns of output (no =>
in-between), simply change .say
to .put
. Or if you prefer a more 'Raku-ish' output, try using .raku.say
, which returns the following:
:A(4)
:B(2)
:C(1)
:D(2)
:E(1)
https://docs.raku.org/routine/dir
https://docs.raku.org/type/Bag
https://raku.org