![디렉터리의 모든 파일에 대해 열의 특정 값이 있는 행 수를 반복적으로 계산합니다.](https://linux55.com/image/33854/%EB%94%94%EB%A0%89%ED%84%B0%EB%A6%AC%EC%9D%98%20%EB%AA%A8%EB%93%A0%20%ED%8C%8C%EC%9D%BC%EC%97%90%20%EB%8C%80%ED%95%B4%20%EC%97%B4%EC%9D%98%20%ED%8A%B9%EC%A0%95%20%EA%B0%92%EC%9D%B4%20%EC%9E%88%EB%8A%94%20%ED%96%89%20%EC%88%98%EB%A5%BC%20%EB%B0%98%EB%B3%B5%EC%A0%81%EC%9C%BC%EB%A1%9C%20%EA%B3%84%EC%82%B0%ED%95%A9%EB%8B%88%EB%8B%A4..png)
내 디렉터리에 40개의 파일이 있고 각 파일의 첫 번째 열에 "2"가 포함된 행 수를 개별적으로 계산하고 싶습니다.
나는 이와 같은 것을 시도하고 있지만 각 파일의 합계를 인쇄하고 개별 합계를 원합니다.
find . -type f -print0 | xargs -0 awk '($1=="2"){++count} END {print count}'
명확성을 위해 다음 예를 들어보겠습니다.
파일 1
2 345 123 4
2 4567 2344 6
3 2345 657 87
6 234 345 6
파일_2
1 12 436 7
2 54 86 8
2 23 48 0
2 098 0 8
8 98 9 0
인쇄:
FILE_1 2
FILE_2 3
내가 실제로 얻는 것은 다음과 같습니다.
인쇄:
5
당신의 도움을 주셔서 감사합니다!
답변1
내가 숫자를 세는 것을 도와 주실 수 있습니다 grep
. 필요한 줄이 로 시작한다고 가정하면 2
다음을 사용할 수 있습니다.
grep -c '^[[:space:]]*2\>' $(find . -type f -print0 | xargs -0 echo)
정규 표현식의 끝 부분 에서는 \>
2 대신 20으로 시작하는 줄과 같은 잘못된 긍정을 피하기 위해 일치가 "단어 경계"에서 중지되도록 합니다.
노트:
찾고 있는 "40개 파일"이 모두 동일한 디렉터리(하위 디렉터리가 아님)에 있는 경우 find
다음과 같이 반복 없이(대기 시간을 줄이기 위해) 현재 디렉터리를 검색할 수 있습니다.
find -maxdepth 1 . -type f -print0
고쳐 쓰다:
첫 번째 열과 다른 열에 나타나는 2개의 파일을 일치시키려면 다음을 수행할 수 있습니다.
COLNUM=3
TOMATCH=$(($COLNUM-1))
grep -cE "^[[:space:]]*([0-9]+[[:space:]]+){$TOMATCH}2\>" \
$(find . -type f -print0 | xargs -0 echo)
COLNUM
필요에 따라 변경할 수 있습니다 . 기본적으로 이 기능은 COLNUM-1
단어 경계에서 열 뒤에 2가 오는지 일치시키려고 시도합니다. -E
이 스위치는 기호를 사용하여 숫자 한정자를 지정할 수 있는 확장 정규식을 활성화하는 데 필요합니다 {}
(예: "이전 패턴과 두 번 이상 일치").
그러나 파일에 존재하지 않는 열 번호를 입력하면 정규 표현식이 자동으로 실패합니다.
답변2
몇 가지 해결 방법:
awk
다음 옵션을 사용하여 각 파일을 실행합니다find
-exec
.find . -type f \ -exec awk '($1=="2"){++count}END{print FILENAME ": " count}' {} \;
awk
FNR
변수를 사용하여 awk 스크립트에서 파일 변경을 감지합니다.find . -type f -print0 | xargs -0 \ awk 'FNR==1{if (NR!=1){print count} printf("%s: ", FILENAME);}($1=="2"){++count}END{print count}'
답변3
출력을 변경해도 괜찮다면 다음을 수행할 수 있습니다.
$ grep "^2" *|awk '{print $1}'|uniq -c
2 FILE_1:2
3 FILE_2:2
인쇄를 원하시면:
$ grep "^2" *|awk '{print $1}'|uniq -c|sed 's/:2//'|awk '{print $2, $1}'
FILE_1 2
FILE_2 3