![선택한 파일 평균화 및 이동](https://linux55.com/image/77666/%EC%84%A0%ED%83%9D%ED%95%9C%20%ED%8C%8C%EC%9D%BC%20%ED%8F%89%EA%B7%A0%ED%99%94%20%EB%B0%8F%20%EC%9D%B4%EB%8F%99.png)
나는 다음과 같이 디렉토리 이름에 따라 이름이 지정된 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
평균이 가장 높은 테이블을 다른 디렉터리로 이동하려고 합니다.b
a
a1.txt a2.txt a3.txt a4.txt
b
b1.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.txt
sum 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’
파일 이름에 공백이나 와일드카드가 포함되어 있으면 중단됩니다.