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
awk
just 및 다음을 사용하여 모든 작업을 수행할 수도 있습니다 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
컷 재검토
위의 방법은 OK 작업을 수행하지만 특정 열의 값 내에 공백이 있는 줄을 처리하지 않습니다. 예를 들어 "Dept Manager" get이 있는 줄은 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 '{
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
awk FIELDWIDTHS
GNU 변형을 사용하는 경우 awk
변수를 사용하여 FIELDWIDTHS
각 필드의 정적 크기를 지정할 수 있습니다. substr
액세스할 수 있는 경우 이 방법이 메서드보다 훨씬 깔끔해집니다 . 또한 별도의 필드로 구문 분석될 필드를 효과적으로 서로 붙일 수 있습니다.
$ 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}'
필드와 값을 다시 작성하고 싶지 않다면 그렇게 하는 것이 더 나을 수도 있습니다 .