루프 및 awk를 사용하여 각 열의 최대 문자 길이 찾기

루프 및 awk를 사용하여 각 열의 최대 문자 길이 찾기

문서를 반복하면서 열에서 가장 높은 문자 길이를 찾아 반환하는 스크립트를 만들려고 합니다. 내 목표는 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그렇지 않았습니다. 해당 작업을 수행하지 않았을 것입니다).

관련 정보