폴더에 있는 파일 이름의 첫 번째 밑줄과 두 번째 밑줄 사이의 문자를 추출하고 그 안에 있는 파일 유형의 수를 계산하고 싶습니다.
폴더에는 다음과 같은 특정 형식의 파일이 포함되어 있습니다.
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
등등…
스크립트 출력은 다음과 같은 결과를 제공해야 합니다.
ABC 3
DEF 3
MNO 2
답변1
ls | cut -d_ -f2 | sort | uniq -c
답변2
작은 명령을 함께 연결하여 고전적인 *nix 방식으로 이 작업을 수행할 수 있습니다. 먼저 관심 있는 파일을 찾으십시오. 이를 위해 쉘을 사용할 수 있습니다글로빙:
for i in *_*_*; do echo "$i"; done
이 명령은 이름에 두 개의 밑줄이 포함된 현재 디렉터리의 모든 파일을 인쇄합니다. 밑줄 사이의 문자열을 추출하려면 다음을 사용할 수 있습니다.cut
_
, 필드 구분 기호로 사용하고 두 번째 필드를 인쇄하도록 지시합니다 .
cut -d '_' -f 2
첫 번째 명령을 두 번째 명령으로 파이프하면 관심 있는 문자열이 인쇄되지만 밑줄 사이에 문자가 없는 경우( foo__bar
예를 들어) 빈 줄도 인쇄됩니다. grep .
최소한 하나의 문자(공백 포함)가 포함된 줄만 인쇄하는 기능을 사용하여 필터링할 수 있습니다 . 마지막으로 출력을 다음을 통해 전달하여 계산할 수 있습니다.sort
그리고uniq -c
.
이를 모두 합치면 다음과 같은 이점이 있습니다.
$ for i in *_*_*; do echo "$i" | cut -d '_' -f 2 ; done |
grep . | sort | uniq -c
3 ABC
2 DEF
1 MNO
번호를 반대편에 표시하려면 다음을 사용할 수 있습니다 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
답변3
Perl을 사용하여 작업을 수행하는 방법은 다음과 같습니다.
perl -aE '/^[^_]+_\K[^_]+/ && $h{$&}++}{say$_," ",$h{$_} for sort keys %h' file
ABC 3
DEF 3
MNO 2
설명:
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