Gostaria de extrair caracteres entre o primeiro e o segundo sublinhados dos nomes de arquivos em uma pasta e contar esses tipos de arquivos presentes nela.
A pasta contém arquivos em um formato específico, como:
2305195303310_ABC_A08_1378408840043.hl7
2305195303310_ABC_A08_1378408840043.hl7
Q37984932T467566261_DEF_R03_1378825633215.hl7
37982442T467537201_DEF_R03_1378823455384.hl7
37982442T467537201_MNO_R03_1378823455384.hl7
2305195303310_ABC_A08_1378408840053.hl7
Q37984932T467566261_DEF_R03_1378825633215.hl7
37982442T467537201_MNO_R03_1378823455384.hl7
E assim por diante…
A saída do script deve me dar um resultado como:
ABC 3
DEF 3
MNO 2
Responder1
ls | cut -d_ -f2 | sort | uniq -c
Responder2
Você pode fazer isso da maneira clássica *nix, agrupando pequenos comandos. Primeiro encontre os arquivos de seu interesse, para isso você pode usar shellglobulando:
for i in *_*_*; do echo "$i"; done
Esse comando imprimirá todos os arquivos do diretório atual cujo nome contém dois sublinhados. Para extrair a string entre esses sublinhados, você poderia usarcut
, dizendo para usar _
como delimitador de campo e imprimir o segundo campo:
cut -d '_' -f 2
Canalizar o primeiro comando até o segundo imprimirá as strings de seu interesse, mas também imprimirá uma linha vazia para os casos em que não há nenhum caractere entre os sublinhados ( foo__bar
por exemplo). Você pode filtrá-los usando grep .
which imprimirá apenas linhas que contenham pelo menos um caractere (incluindo espaços em branco). Finalmente, você pode contar passando a saída porsort
euniq -c
.
Juntar tudo dá a você:
$ for i in *_*_*; do echo "$i" | cut -d '_' -f 2 ; done |
grep . | sort | uniq -c
3 ABC
2 DEF
1 MNO
Se você realmente deseja que o número esteja do outro lado, você pode usar awk
:
$ for i in *_*_*; do echo "$i" | cut -d '_' -f 2 ; done |
grep . | sort | uniq -c | awk '{print $2,$1}'
ABC 3
DEF 2
MNO 1
Responder3
Aqui está uma maneira de fazer o trabalho usando Perl.
perl -aE '/^[^_]+_\K[^_]+/ && $h{$&}++}{say$_," ",$h{$_} for sort keys %h' file
ABC 3
DEF 3
MNO 2
Explicação:
perl -aE # invoque Perl compiler with autosplit lines
/^[^_]+_\K[^_]+/ # match non _ characters after the first _
&& # execute the next command if a match is found
$h{$&}++} # increment a counter for each match founded
{say$_," ",$h{$_} # finally print each match and the counter associated
for sort keys %h # for each sorted matches