![스크립트 오류 수정](https://linux55.com/image/10258/%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8%20%EC%98%A4%EB%A5%98%20%EC%88%98%EC%A0%95.png)
방금 파일의 최소값을 찾기 위해 몇 줄을 썼고 올바른 결과를 얻었지만 줄을 두 번 반복하면 오류가 수정되었습니다.
나는 무엇을하고 있는가:
- 모든 파일 찾기
- 헤더 제거
- 아홉 번째 열을 사용하여 과학적 표기법으로 정렬
- awk를 사용하여 정렬하고 인쇄한 다음 가장 작은 첫 번째 줄을 가져옵니다.
- 또한 $i의 파일 이름을 인쇄하고 싶습니다.
스크립트:
#!/bin/bash
for i in `ls -v *.txt`
do
smallestPValue=`sed 1d $i | sort -k9 -g | head -1 | awk '{print $0}'`
echo $i $smallestPValue >> smallesttPvalueAll.txt
done
산출
U1.text 4 rsxxx 1672175 A ADD 759 0.0751 4.918 1.074e-06
U1.txt 4 rsxxxx 1672175 A ADD 759 0.0751 4.918 1.074e-06
U2.txt 16 rsxxxx 596342 T ADD 734 -0.05458 -5.204 2.535e-07
U2.txt 16 rsxxxx 596342 T ADD 734 -0.05458 -5.204 2.535e-07
U3.txt 2 rsxxxx 12426 T ADD 722 0.06825 5.285 1.669e-07
몇 개의 행이 중복되어 있는데 위의 U3가 이미 한 번 나타나기 때문에 일부는 괜찮습니다. 이것이 바로 제가 원하는 것입니다. uniq 또는 sort -u를 통해 중복 행을 쉽게 제거할 수 있지만 원인이 무엇인지 궁금합니다.
원하는 출력이 한 줄에 한 번씩 반복됩니다.
답변1
awk
내가 올바르게 설명하고 있다면 아마도 원하는 것을 수행할 수 있을 것입니다. sort
- 루핑이 필요하지 않습니다. 또는ls를 구문 분석하다(미묘한 힌트:그러지 마세요!), 또는 head
또는 sed
.
awk 'FNR > 1 {print FILENAME, $0}' *.txt | sort -k10 -g | sort -u -k1,1
이는 각 파일의 첫 번째 줄을 건너뛰고 파일 이름과 공백(awk의 기본 출력 레코드 구분 기호 또는 )이 ORS
앞에 붙은 나머지 모든 줄을 인쇄합니다. 그런 다음 정렬을 통해 필드 10에 대한 일반적인 숫자 정렬을 수행합니다. 마지막으로 첫 번째 필드(파일 이름)만 고유하게 정렬하여 -k1,1
해당 파일 이름이 있는 첫 번째 줄만 출력됩니다.
여기에서는 파일 이름을 첫 번째 필드로 추가했기 때문에 필드 9가 아닌 필드 10을 정렬해야 하므로 다른 모든 필드 번호는 1씩 증가합니다.
FNR
FILENAME
내장 awk 변수입니다 . FNR은 현재 파일의 줄 번호(awk-lingo의 "입력 레코드 번호")이고 FILENAME은 현재 파일 이름입니다.
이번에는 다음을 사용하는 또 다른 접근 방식이 있습니다 awk
.
#!/usr/bin/awk -f
FNR > 1 && (! s[FILENAME] || $9 < s[FILENAME]) {
s[FILENAME]=$9;
l[FILENAME]=$0
};
END {
for (f in s) {
print f, l[f]
}
}
예를 들어 로 저장 하고 실행 smallest-pvalue.awk
가능하게 만든 chmod +x smallest-pvalue.awk
후 ./smallest-pvalue.awk *.txt
.
이 awk 스크립트는 이름이 지정된 배열의 각 입력 파일에 대한 필드 9의 최소값을 추적 s
하고 일치하는 입력 행을 배열에 저장합니다 l
.
모든 파일을 처리한 후 파일 이름과 각 파일의 최소 9번째 필드가 포함된 줄을 인쇄합니다.