평균을 생성하는 특정 패턴 옆의 디렉토리 및 합계 값을 반복합니다.

평균을 생성하는 특정 패턴 옆의 디렉토리 및 합계 값을 반복합니다.

디렉토리의 모든 파일을 반복하고 싶습니다.

파일은 다음과 같이 설정됩니다.

<Overall>4
other data
<Overall>2
other data
......

나는 코드를 가지고 있습니다 :

for file in .dat; 
do
awk 'x+=sub(/<Overall>/,""){y+=$0} END{print FILENAME, y/x}' $file
done

이는 파일에 있는 값의 평균을 인쇄하지만 내가 원하는 것은 내 스크립트가 있는 디렉터리를 인수로 가져와 디렉터리의 모든 .dat 파일에 대해 awk 명령을 수행하는 것입니다.

나는 코드를 사용해 보았습니다 :

for file in $1

하지만 오류가 발생합니다.

awk: cmd. line:1: fatal cannot open file `folder' for reading (No such file or directory)

이 외에도 평균값의 출력을 높은 값에서 낮은 값으로 정렬할 수 있기를 원합니다.

답변1

두 가지 변형:

  1. 파일을 반복하고 awk각 파일에 대해 한 번씩 호출하거나
  2. 스크립트에 모든 파일을 제공 awk하고 각각의 평균을 계산하고 진행되는 대로 보고하도록 합니다.

아래 솔루션의 결과 정렬은 출력을 다음을 통해 파이프하여 수행할 수 있습니다.

sort -k2,2rn

두 번째 필드(평균)에서 숫자 역순 정렬을 수행합니다.


첫 번째 해결 방법:

#!/bin/sh

for name in "$1"/*.dat; do
    test -f "$name" || continue   # skip non-files
    awk -F '>' '/<Overall>/ { s+=$NF; n++ } END { print FILENAME, s/n }' "$name"
done

이 스크립트에서는 첫 번째이자 유일한 명령줄 인수로 명령줄의 디렉터리 이름을 예상합니다. 스크립트 awk는 문자열이 포함된 모든 줄을 찾아 해당 줄 뒤의 값을 Overall합산합니다( ). 마지막에는 파일 이름과 함께 평균이 출력됩니다. 변수는 우리가 에 무엇인가를 추가한 횟수를 보유합니다 .s>ns


두 번째 해결 방법(GNU Awk 필요):

#!/bin/sh

find "$1" -maxdepth 1 -type f -name '*.dat' \
    -exec awk -F '>' '/<Overall>/ { s+=$NF; n++ } ENDFILE { print FILENAME, s/n; s=n=0 }' {} +

첫 번째 스크립트와 마찬가지로 이 스크립트는 디렉터리 이름을 유일한 명령줄 인수로 예상합니다. 한 번에 가능한 한 많은 파일로 스크립트를 find실행하는 데 사용됩니다 .awk.dat

스크립트 awk는 GNU Awk의 ENDFILE트리거를 사용하여 계산된 값을 출력하고 각 파일을 처리한 후 다음 파일을 읽기 시작하기 전에 s및 변수를 재설정합니다.n

이것은 다음과 같이 쓰여졌을 수도 있습니다.

#!/bin/sh

awk -F '>' '/<Overall>/ { s+=$NF; n++ } ENDFILE { print FILENAME, s/n; s=n=0 }' "$1"/*.dat

그러나 이는 "$1"/*.dat너무 긴 파일 이름 목록으로 확장하지 않는 것에 의존합니다(또한 각 .dat이름이 일반 파일이어야 하며 이는 위 find명령이 에서 보장하는 것입니다 -type f).

관련 정보