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

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

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

파일에 대한 설정은 다음과 같습니다.

<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(in) 뒤의 값을 합산합니다. 마지막으로 평균값이 파일 이름과 함께 출력됩니다. 이 변수는 우리가 무언가를 추가한 횟수를 보유합니다.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

관련 정보