선택한 파일 평균화 및 이동

선택한 파일 평균화 및 이동

나는 다음과 같이 디렉토리 이름에 따라 이름이 지정된 ASCII 테이블을 포함하는 여러 디렉토리를 가지고 있습니다.

a1/a1.txt
a2/a2.txt
a3/a3.txt
a4/a4.txt
b1/b1.txt
b2/b2.txt
b3/b3.txt
b4/b4.txt

각 파일의 네 번째 열의 평균 (so)과 (so)를 계산하여 4개의 다른 파일을 선택하고 a평균이 가장 높은 테이블을 다른 디렉터리로 이동하려고 합니다.baa1.txt a2.txt a3.txt a4.txtbb1.txt b2.txt b3.txt b4.txt

따라서 다음과 같은 경우:

a1.txt average value = 1
a2.txt average value = 0.25
a3.txt average value = 2
a4.txt average value = 1.15
b1.txt average value = 3
b2.txt average value = 1.7
b3.txt average value = 0.25
b4.txt average value = 2

그런 다음 a3.txt및를 b1.txt원격 디렉토리로 이동해야 합니다.

다음 코드가 있습니다.

for x in a b
do
  RESULT=$(awk '{x+=$4} END{print x/NR, FILENAME}' ${x}[1-4]/${x}[1-4].txt | sort -n -r| head -1)
  highest="$(echo $RESULT | cut -d ' ' -f1 )"
  hifile="$(echo $RESULT | cut -d ' ' -f2 )"
  echo "highest was $highest in $hifile"
  cp "$hifile" "high_dis/${x}.txt"
done

하지만 이 코드는 4개 파일의 평균을 계산한 다음 마지막 파일( a4.txtsum b4.txt) 을 복사합니다.

원하는 출력을 얻는 방법을 아는 사람이 있습니까?

답변1

귀하의 문제는 다음 사실로 인해 발생합니다awk는 모든 입력 파일을 읽은 후에만 END 절에 도달합니다..

루프의 첫 번째 줄을 for다음으로 바꾸면 문제가 해결됩니다.

RESULT=$(awk 'BEGIN{curr_f=FILENAME; nr=1} {if(curr_f!=FILENAME){if(mean > max_mean){max_mean=mean; f=curr_f} curr_f=FILENAME; nr=0; sum=0} } { sum+=$4; nr++; mean=sum/nr }  END{if(mean>max_mean){print mean, FILENAME}else{print max_mean, f}}' ${x}[1-4]/${x}[1-4].txt )

답변2

나는 약간 다른 접근 방식을 사용하고 awk에서 직접 더 많은 작업을 수행합니다. 먼저, FNR새 파일이 처리될 때마다 1을 반환하고 awk모든 a- 또는 b- 파일을 한 번에 제공하는 것을 사용하십시오.awk

$ for f in a b; do 
    awk '(FNR==1 && n>1){
            av=x/n;if(av>max){
                max=av;f=FILENAME
            }
        x=0; n=0
        }
        {x+=$4;n=FNR} 
        END{ 
            if(x/n>max){print x/n,FILENAME}
            else{print max,f}'
        } "$f"[1..4]/"$f"[1..4].txt; done
18898.4 a3.txt
18806 b4.txt

이를 통해 평균이 가장 큰 두 파일을 얻을 수 있습니다. 이를 이동하려면 이전 스크립트의 출력에서 ​​값을 제거하고 파일 이름만 유지한 후 명령에 직접 전달하면 됩니다 cp.

$ cp -v $(for f in a b; do awk '(FNR==1 && n>1){av=x/n;if(av>max){max=av;f=FILENAME};x=0;n=0}{x+=$4;n=FNR} END{if(x/n>max) print x/n,FILENAME; else print max,f}' "$f"[1-4]/"$f"[1..4].txt; done) bar/
‘a3.txt’ -> ‘bar/a3.txt’
‘b4.txt’ -> ‘bar/b4.txt’

파일 이름에 공백이나 와일드카드가 포함되어 있으면 중단됩니다.

관련 정보