sed, awk, grep 및 wc를 사용하여 bash 루프 형식을 지정하는 방법

sed, awk, grep 및 wc를 사용하여 bash 루프 형식을 지정하는 방법

그래서 특정 줄을 추출하고 특정 열의 숫자가 나타나는 횟수를 계산하는 데 필요한 텍스트 파일이 있습니다. 이 파일이 약 100개 정도 있습니다. 작은 단계로 완료할 수 있지만 bash/ksh를 사용하여 완료하고 싶습니다.

foreach i *h3
sed '4p;55p;77q;d' $i >> output.txt
end 

^^^^이것은 각 h3 파일에서 필요한 라인을 추출합니다.

awk '{print $6}' output.txt | grep 'P2' | wc -l

^^^이것은 단지 output.txt에서 열 6을 추출하고 P2가 열 6에 나타나는 횟수를 계산합니다.

이 모든 것을 bash/ksh 스크립트로 결합할 수 있는 방법이 있나요?

답변1

내가 올바르게 이해했다면:

  • 몇 개의 파일(*h3이라는 이름) 중 4,55,77행의 6번째 필드 내에 "P2"가 몇 번이나 있는지 계산하고 싶습니까?

1 awk로 이 작업을 수행할 수 있습니다.

awk '
( FNR==4 || FNR==55 || FNR==77 ) {
    if ( $6 ~ "P2" ) { occurence++ } 
}
END {
    printf "There was: %d P2 ", occurence
    printf " among the 6th field on lines 4,55 or 77 of the *h3 files\n"
}' *h3

참고: 정확한 일치를 원하는 경우 $6 ~ "P2"로 변경하십시오 $6 == "P2"(자신의 예에서 사용한 것처럼 grep 대신: somethingP2otherthing및 그 변형도 일치하도록).

FNR = 파일의 레코드 수 = 현재 파일의 라인 수(즉, 각 파일의 첫 번째 라인에서 1부터 다시 시작)(내부 변수로도 이름을 알 수 있는 현재 파일: FILENAME)

(NR = 여기에서는 작동하지 않습니다. 이는 시작 이후(현재 파일의 시작 이후가 아님) 읽은 (총) 숫자 또는 레코드이기 때문입니다.)

답변2

확신하는. 여기에 한 가지 방법이 있습니다

p2_count=0
for f in *h3; do
    for ((n=1; n<=77; n++)); do
        IFS= read -r line
        if [[ $n == 4|55|77 ]]; then
            echo "$line"
            set -f
            set -- $line
            set +f
            if [[ $6 == *P2* ]]; then
                ((p2_count++))
            fi
        fi
    done < "$f"
done > output.txt
echo "saw P2 in 6th column $p2_count times"

답변3

또는세게 때리다짧막 한 농담:

for i in *h3; do sed '4p;55p;77q;d' $i | awk '{print $6}' | grep 'P2'; done | wc -l

또는 다음을 사용하여 더 짧게 grep -c:

for i in *h3; do sed '4p;55p;77q;d' $i | awk '{print $6}'; done | grep -c 'P2'

답변4

일반적으로 질문이 "다음을 사용하여 여러 텍스트 파일을 처리하려면 어떻게 해야 합니까?"라고 묻는 경우특정 도구bash 루프에서?"에 대한 대답은 부분적으로 "bash 루프를 사용하지 말고 도구 자체(일부 또는 전부)를 사용하십시오"입니다. 때로는 대답의 일부가 "사용하지 마십시오"입니다. 그 도구는 대신 이것을 사용하세요."

원하는 것은 awk쉘 루프 없이 혼자서 수행할 수 있습니다. 또는 sed또는 grep또는 wc:

awk 'BEGIN {OFS="\t"}
     FNR ~ /^(4|10|17)$/ && $6 ~ /P2/ {count++}
     ENDFILE { print FILENAME, count; count=0 }' *h3

메모:엔드파일 GNU에만 해당됩니다 awk. 다른 버전에서는 작동하지 않습니다 awk.

또한 이 버전은 모든 파일의 누적 합계도 인쇄합니다.

awk 'BEGIN {OFS="\t"}
     FNR ~ /^(4|10|17)$/ && $6 ~ /P2/ {count++; total++}
     ENDFILE { print FILENAME, count; count=0 }
     END { print "---", total,"total" }' *h3

블록 END{}은 총계를 인쇄하고 파일 이름이 "total"인 파일과 실제 총계를 구별하기 위한 대략적인 시도도 수행합니다. 첫 번째 필드에 인쇄한 다음 합계를 인쇄하고 세 번째 필드에 ---문자열을 인쇄하여 이를 수행합니다 . total이는 완벽과는 거리가 멀지만 많은 경우에 충분합니다. wc전혀 시도하지 않는 것보다 낫습니다 .

관련 정보