Cut 명령이 정렬된 열의 필드를 올바르게 추출하지 않습니다.

Cut 명령이 정렬된 열의 필드를 올바르게 추출하지 않습니다.

필드 3, 4, 5, 8을 잘라야 하는 텍스트 파일이 있습니다.

219 432 4567 Harrison     Joel     M 4540 Accountant      09-12-1985
219 433 4587 Mitchell     Barbara  C 4541 Admin Asst      12-14-1995
219 433 3589 Olson        Timothy  H 4544 Supervisor      06-30-1983
219 433 4591 Moore        Sarah    H 4500 Dept Manager    08-01-1978
219 431 4527 Polk         John     S 4520 Accountant      09-22-1998
219 432 4567 Harrison     Joel     M 4540 Accountant      09-12-1985
219 432 1557 Harrison     James    M 4544 Supervisor      01-07-2000

기본 구분 기호는 탭이므로 필드를 추출하는 명령은 다음과 같습니다.

cut -f 3,4,5,8 filename

문제는 출력이 원본 파일 내용과 동일하다는 것입니다. 여기서 무슨 일이 일어나고 있는 걸까요? 왜 이것이 작동하지 않습니까?

답변1

열 사이의 공백이 모두 탭처럼 보이는 것은 아니므로 cut원하는 작업을 수행할 수 없습니다. 를 사용하는 것이 좋습니다 awk. cut수행하려는 작업과 같이 데이터 열을 구문 분석하는 것 보다 더 유연합니다 .

$ awk '{print $3,$4,$5,$8}' data.txt

$ awk '{print $3,$4,$5,$8}' data.txt 
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor

다음 명령을 사용하여 출력 간격을 늘릴 수도 있습니다 column.

$ awk '{print $3,$4,$5,$8}' data.txt |column -t
4567  Harrison  Joel     Accountant
4587  Mitchell  Barbara  Admin
3589  Olson     Timothy  Supervisor
4591  Moore     Sarah    Dept
4527  Polk      John     Accountant
4567  Harrison  Joel     Accountant
1557  Harrison  James    Supervisor

awkjust 및 다음을 사용하여 모든 작업을 수행 할 수도 있습니다 printf.

$ awk '{printf "%s\t%-20s\t%s\n",$3,$4" "$5,$8}' data.txt 
4567    Harrison Joel           Accountant
4587    Mitchell Barbara        Admin
3589    Olson Timothy           Supervisor
4591    Moore Sarah             Dept
4527    Polk John               Accountant
4567    Harrison Joel           Accountant
1557    Harrison James          Supervisor

클립을 다시 살펴보세요.

위의 방법은 훌륭하지만 특정 열의 값에 공백이 있는 행을 처리하지 않습니다. 예를 들어, "Dept Manager"가 포함된 행은 "Dept"로 잘립니다.

데이터가 그림과 같이 구조화되어 있다는 것을 보장할 수 있다면 이를 사용할 수 있지만 cut구분 기호로 분할하는 대신 표시할 문자의 실제 위치만 사용할 수 있습니다.

이렇게 하면 파일에서 텍스트가 잘리고 data.txt위치 9~13, 14~35 등의 모든 내용이 인쇄됩니다.

$ cut -c 9-13,14-35,43-58 data.txt 
4567 Harrison     Joel     Accountant      
4587 Mitchell     Barbara  Admin Asst      
3589 Olson        Timothy  Supervisor      
4591 Moore        Sarah    Dept Manager    
4527 Polk         John     Accountant      
4567 Harrison     Joel     Accountant      
1557 Harrison     James    Supervisor      

awk를 다시 방문하세요.

구분 기호가 아닌 위치를 기반으로 awk 추출 텍스트를 만들 수도 있습니다. 더 자세하지만 완전성을 위해 구현 방법은 다음과 같습니다.

$ awk '{
    printf "%s\t%-20s\t%s\n",substr($0,9,5),substr($0,14,22),substr($0,43,16)
  }' data.txt
4567    Harrison     Joel       Accountant      
4587    Mitchell     Barbara    Admin Asst      
3589    Olson        Timothy    Supervisor      
4591    Moore        Sarah      Dept Manager    
4527    Polk         John       Accountant      
4567    Harrison     Joel       Accountant      
1557    Harrison     James      Supervisor      

이상한 필드 너비

GNU 변형을 사용하는 경우 이 변수를 사용하여 각 필드의 정적 크기를 지정할 awk수 있습니다 . 접근할 수 있다면 이 방법이 그 방법보다 훨씬 깔끔합니다. 별도의 필드로 구문 분석될 필드를 효과적으로 서로 붙일 수도 있습니다.FIELDWIDTHSsubstr

$ awk 'BEGIN { FIELDWIDTHS="4 4 5 24 5 16 11" }{ print $3,$4,$5,$6 }' data.txt 
4567  Harrison     Joel     M  4540  Accountant      
4587  Mitchell     Barbara  C  4541  Admin Asst      
3589  Olson        Timothy  H  4544  Supervisor      
4591  Moore        Sarah    H  4500  Dept Manager    
4527  Polk         John     S  4520  Accountant      
4567  Harrison     Joel     M  4540  Accountant      
1557  Harrison     James    M  4544  Supervisor      

답변2

내 생각엔 이것이 라벨이 아니라고 생각합니다. 탭이라고 생각하지 않는 이유는 파일을 복사하여 붙여넣고 필드를 수동으로 표로 만들면 cut -f 3,4,5,8 filename제대로 작동하는 것 같기 때문입니다. cat filename | awk '{print $3, $4, $5, $8}'필드와 값을 다시 만들고 싶지 않다면 이 작업을 수행하는 것이 좋습니다.

관련 정보