awk를 사용하여 한 줄을 여러 공백 대신 단일 공백으로 분할

awk를 사용하여 한 줄을 여러 공백 대신 단일 공백으로 분할

내가 제어할 수 없는 형식의 줄을 분할하려고 합니다. 매개변수 7과 8이 누락된 경우 공백으로 대체될 수 있으므로 결국 다음과 같이 됩니다.

field1 field2 field3 field4 field5 field6   field9

현재 이 경우 필드 9는 필드 7로 읽혀집니다. 많은 검색을 통해 다음이 작동해야 한다고 믿게 되지만 그렇지 않습니다. 이것은 내 부분의 작은 문법 오류일 수 있지만 그것을 발견할 수 없는 것 같습니다.

word1=`echo $LINE | awk 'BEGIN { FS="[ ]" } ; { print $9 }'`

답변1

LINE 매개변수는 인용되지 않으므로 in wordsplitting확장이 발생하고 입력이 수신될 때까지 7(셸에서 볼 수 있듯이)이 되며 모두 공백으로 구분됩니다. awk가 이를 처리하기 전에 행의 공백이 손상되지 않도록 echo를 출력으로 제공하기를 원합니다(다시 쉘에서 볼 수 있음). 이것이 참조 매개변수가 방지하는 것입니다.$LINEecho $LINEawkwordsword

# How you want it to be given to awk:
$ printf '<%s> ' "$LINE"; echo
<field1 field2 field3 field4 field5 field6   field9> 
# Your attempt:
$ printf '<%s> ' $LINE; echo
<field1> <field2> <field3> <field4> <field5> <field6> <field9> 

필드 6과 9 사이의 추가 공간이 어떻게 사라지는지 확인하세요.

항상 확장자를 인용해야 합니다. 확장자를 인용하지 않으면 인용하는 것보다 문제가 발생할 가능성이 더 높습니다.

답변2

가변 입력 길이를 처리할 때 awk에서 매우 유용한 매개변수는 필드 수인 NF입니다.

lastword=`echo $LINE | awk '{ print $NF }'`

누락된 열에 관계없이 항상 마지막 열을 인쇄합니다. 중간에 일부 필드가 누락된 경우 마지막 필드에서 거꾸로 계산하는 것도 잘 작동합니다.

예제와 같이 공백으로 채워진 누락/빈 열이 있는 예제 파일은 다음과 같습니다.

line1 field1 field2 field3 field4 field5 field6 field7 field8 field9
line2 field1 field2 field3 field4 field5 field6  field8 field9
line3 field1 field2 field3 field4 field5   field8 field9

그리고

awk '{print $1 " " $2 " " $(NF-1) " " $NF}' file

    line1 field1 field8 field9
    line2 field1 field8 field9
    line3 field1 field8 field9

답변3

이 작업을 수행할 수 있어야 합니다 ksh93.

set -f
IFS='  ' # two spaces
set -- $LINE
printf '%s\n' "$9"

공백을 두 배로 늘리면 에 표시된 것처럼 일련의 공백이 하나로 처리되고 선행 및 후행 공백이 무시되는 특수 동작이 제거됩니다 zsh.

답변4

내 경우에는 먼저 파이프를 연결하기로 결정했습니다 tr. 입력에 나타날 가능성이 없는 문자(이 경우 벨 코드 \a)에 공백을 매핑하면 됩니다.

❯ echo 'a b  d' | tr ' ' '\a' | awk -F'\a' '{print "1="$1, "2="$2, "3="$3, "4="$4}'
1=a 2=b 3= 4=d

이제 세 번째 필드 $3가 비어 있습니다.


한 시간 후에 다시 만나요.

관련 정보