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만 추출하고 열 6에 P2가 몇 번 나타나는지 계산합니다.

이 모든 것을 bash/ksh 스크립트로 결합하는 방법이 있습니까?

답변1

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

  • 여러 파일(*h3이라는 이름) 중 4,55, 77행의 6번째 필드에 있는 "P2"를 몇 번이나 계산하시겠습니까?

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

참고: 정확한 일치를 원할 경우 (귀하의 예에서 사용한 것과 같이 grep 대신에: 및 그 변형도 일치하도록) $6 ~ "P2"로 변경하십시오.$6 == "P2"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전혀 노력하지 않는 것보다 낫습니다 .

관련 정보