awk는 잘못된 열의 필드를 인쇄합니다.

awk는 잘못된 열의 필드를 인쇄합니다.

다음 명령을 실행하면 아래와 같이 열 목록이 출력됩니다.

# rancher clusters
CURRENT   ID        STATE     NAME                           PROVIDER  
*         abcd      active    test-cluster                   Imported
          efgh      active    prod-cluster                   Imported
          xyzd      active    dev-cluster                    Imported

NAME 열을 인쇄하려고 하면 test-cluster가 결과에 반환되지 않습니다.

# rancher clusters | awk '{print $3}'
STATE
active
prod-cluster
dev-cluster

인쇄된 NAME 열에 표시된 STATE 열의 일부를 볼 수 있습니다.

네 번째 열을 인쇄하면 테스트 클러스터가 NAME과 함께 반환됩니다.

# rancher clusters | awk '{print $4}'
NAME
test-cluster
Imported
Imported

awk가 인쇄된 정확한 열의 값을 반환하지 않는 이유는 무엇입니까? 한 열의 값이 다른 열로 반환되는 원인은 무엇입니까? 내 기대는 $3를 인쇄하면 네 번째 열(이름)에 있는 모든 결과를 얻을 수 있다는 것입니다.

답변1

Get $3- 그러나 기본적으로 awk는 레코드를 필드로 나눌 때 선행 및 후행 공백을 무시합니다.

필드 구분 기호를 명시적으로 설정하여 선행 공백을 빈 필드로 처리하도록 강제할 수 있어야 합니다.

$ cat clusters | awk -F'[ \t]+' '{print $3}'
STATE
active
active
active

하지만

$ cat clusters | awk '{print $3}'
STATE
active
prod-cluster
dev-cluster

답변2

awk는 구분 기호를 기준으로 문자열을 분할합니다(기본값은 하나 이상의 공백, 즉 탭 또는 공백). 더 명확하게 하기 위해 여기에 귀하의 데이터가 있습니다. 데이터는 다음에서 제공됩니다.|

CURRENT|ID|STATE|NAME|PROVIDER
*|abcd|active|test-cluster|Imported
efgh|active|prod-cluster|Imported
xyzd|active|dev-cluster|Imported

위에서 볼 수 있듯이 첫 번째 줄 $1은 is CURRENT, $2is ID등입니다. 두 번째 줄 $1은 is *, $2is abcd등입니다. 그러나 세 번째 행은 ID 열에 해당하는 $1입니다 . efghCURRENT 열에는 공백 외에는 아무것도 없기 때문에 awk는 이를 무시하고 $33행과 4행의 NAME을 표시합니다.

당신이 해야 할 일은 첫 번째 열을 awk로 보내기 전에 삭제하는 것뿐입니다. 다음 명령을 사용하면 됩니다.

rancher clusters | cut -b 8- | awk '{ print $3 }'

cut위 파이프라인의 명령은 각 줄의 처음 7바이트를 삭제하고 나머지는 STDOUT에 인쇄합니다. 이렇게 하면 awk각 행의 열 수가 달라도 혼동이 발생하지 않습니다.

답변3

기본적으로 awk는 선행 및 후행 공백을 무시하고 연속적인 공백 시퀀스를 기반으로 레코드를 필드로 구분합니다. 첫 번째 "필드"는 때때로 비어 있어서 awk가 존재하지 않습니다. 이를 감안할 때 NAME 열을 인쇄하는 방법에는 여러 가지가 있으며 가장 간단한 방법은 레코드의 시작 부분이 아닌 끝 부분부터 필드 수를 계산하는 것입니다.

$ awk '{print $NF}' file
PROVIDER
Imported
Imported
Imported
$
$ awk '{print $(NF-1)}' file
NAME
test-cluster
prod-cluster
dev-cluster
$
$ awk '{print $(NF-2)}' file
STATE
active
active
active
$
$ awk '{print $(NF-3)}' file
ID
abcd
efgh
xyzd
$
$ awk '{print (NF>4 ? $(NF-4) : "")}' file
CURRENT
*


$

$(NF-4)NF가 4일 때 인쇄 되지 않도록 마지막 항목에 대해 몇 가지 계산을 수행해야 합니다 $0. 4를 하드코딩하는 대신 헤더 행에 있는 필드 수를 계산하여 예상 필드 수를 계산할 수 있습니다.

$ awk 'NR==1{max=NF-1} {print (NF>max ? $(NF-max) : "")}' file
CURRENT
*


$

답변4

문제는 rancher명령 출력에 한 줄에 5개의 필드가 있는 경우도 있고 4개의 필드가 있는 경우도 있다는 것입니다.

NF다음 awk 한 줄 문은 주어진 입력 줄에 있는 필드 수에 따라 올바른 필드를 인쇄 합니다 ( awk의 내장 변수 사용 ).

$ awk 'NF==5 {print $4}; NF==4 {print $3}' clusters.txt
NAME
test-cluster
prod-cluster
dev-cluster

또는 빈 줄이 없다고 확신하는 경우 다음을 사용할 수 있습니다.

$ awk '{print $(NF-1)}' clusters.txt 
NAME
test-cluster
prod-cluster
dev-cluster

빈 줄이 있으면 다음과 같은 오류 메시지가 나타납니다.

awk: cmd. line:1: (FILENAME=clusters.txt FNR=5) fatal: attempt to access field -1

이는 다음을 통해 피할 수 있습니다.

awk 'NF>=1 {print $(NF-1)}' clusters.txt 

관련 정보