문서를 반복하면서 열에서 가장 높은 문자 길이를 찾아 반환하는 스크립트를 만들려고 합니다. 내 목표는 10,11,14,51인 동안 스크립트는 78,78,78,78을 반환합니다.
for ((i=1;i<=4;i++)); do
awk -F"|" '{ print length($i) }' contact_d.csv | sort -nr | sed '1!d';
done
contact_d.csv
다음을 포함합니다: (더미 데이터 참고) 및 해당 예
Barrera|Wilkinson|(09) 1466 1886|[email protected]
Hopkins|Sellers|(07) 3814 2364|[email protected]
Hunter|Calderon|(01) 3984 0139|[email protected]
for 루프가 내 목표를 반환하지 않는 이유를 아는 사람이 있습니까?
답변1
다음 코드가 작동합니다.
awk -F'|' '{for (i=1;i<=NF;i++) {len=length($i); if (len>lval[i]) {lval[i]=len; lpos[i]=FNR;}}} END{for (i in lval) printf("Longest value of column %d: %d (line %d)\n",i,lval[i],lpos[i])}' contact_d.csv
위의 예에서는 다음을 반환합니다.
Longest value of column 1: 7 (line 1)
Longest value of column 2: 9 (line 1)
Longest value of column 3: 14 (line 1)
Longest value of column 4: 26 (line 2)
각 행에 대해 스크립트는 모든 필드(1부터
NF
필드 수까지)를 반복하고 필드 길이(변수에 임시 저장됨l
)가 지금까지 발견된 가장 긴 길이(필드에 저장됨)보다 큰지 확인합니다lval
. =column) 숫자 인덱스 아래의 배열 변수에 있습니다.첫 번째 줄에서는
lval
아직 초기화되지 않았습니다.그것은 마치 것처럼 행동할 것이다모두lval[i]
0입니다(실제로는 그보다 더 복잡합니다).i
현재 줄 필드의 길이가 에 저장된 값보다 긴 경우lval[i]
스크립트는 필드의 현재 길이lval[i]
와 현재 줄 번호("auto" 변수를 통해 액세스 가능FNR
)를 배열 변수에 저장합니다lpos
.파일 끝(
END
조건)에서는 모든 열의 가장 긴 길이와 해당 위치를 인쇄합니다. 루프를 사용하여for (i in lval)
모든 구성을 살펴봅니다.색인배열에 존재하므로lval
추가 변수에 열 수를 저장할 필요가 없습니다(이와 같은 경우 필요함for (i=1;i<=ncols;i++)
).블록 에서는END
"필드 수"의 개념이 다소 불분명해집니다. 하지만 실제로는awk
액세스할 때 파일의 마지막 줄에 해당하는 값이 일반적으로 사용됩니다.).
쉘 루프에서 호출할 필요가 거의 없습니다 awk
. 루프에서 수행해야 하는 대부분의 작업을 수행할 수 있습니다.
초기 시도가 실패한 이유는 코드가 작은따옴표로 묶인 스크립트 $i
에 쉘 변수( )를 제공 하려고 시도했지만(제안된 대로) 작은따옴표로 인해 쉘 변수의 해석이 꺼집니다. awk
그렇지 않았습니다. 해당 작업을 수행하지 않았을 것입니다).