awk를 사용할 때 발생하는 문제

awk를 사용할 때 발생하는 문제

awk나 다른 방법을 사용하는 데 도움을 줄 수 있나요?

입력 파일에는 다음 내용이 포함되어 있습니다.

PROD   192.168.100.25   Unix                       Active
PROD   192.168.100.26   Unix - Server              Active
DEV    192.168.100.27   windows Gateway            Active
TEST   192.168.100.28   Unix Test Server           Not Active
PROD   192.168.100.29   windows mail gateway       Active down 
PROD   192.168.100.30   Unix                       Active down

이제 awk를 사용하여 열 2와 4를 얻으십시오. 아래를 참조하십시오.

awk '{print $2  $4}' Inputfile

결과-

192.168.100.25   Active                       
192.168.100.26   -               
192.168.100.27   Gateway             
192.168.100.28   Test           
192.168.100.29   mail        
192.168.100.30   Active

예상되는 결과-

192.168.100.25   Active                       
192.168.100.26   Active               
192.168.100.27   Active             
192.168.100.28   Not Active           
192.168.100.29   Active down        
192.168.100.30   Active down  

답변1

기본적으로 AWK의 필드는 공백으로 구분됩니다. 공백이 얼마나 많은지는 상관하지 않으므로 다음과 같은 파일은 동일한 결과를 제공합니다.

PROD   192.168.100.25   Unix   Active
PROD   192.168.100.26   Unix   -        Server   Active

이 두 행의 네 번째 필드는 분명히 Activesum 입니다 -.


이제 파일 형식은 실제로 다음과 같을 수 있습니다. 필드는 탭으로 구분되고 그 사이에는 공백만 포함됩니다. SE에 게시한 후 탭이 유지되지 않는다고 생각하며 표시되는 간격이 8열 너비 탭의 간격과 정확히 일치하지 않지만 어쨌든 참고할 것입니다.

그러면 선이 더 비슷해 보일 것입니다.

PROD<tab>192.168.100.26<tab>Unix - Server<tab><tab>Active

다음과 같이 탭을 구분 기호로 사용하도록 AWK에 지시할 수 있습니다.

$ awk -F '\t+' '{print $2, $4}' file.txt
192.168.100.25 Active
192.168.100.26 Active

하지만 각 필드 사이에 탭을 두는 것이 더 일반적입니다. 즉, 가변 길이 데이터와 잘 맞지 않습니다. 그런 다음 awk -F '\t'.


열이 실제로 고정 너비인 경우 다음을 사용하여 cut필요한 부분을 선택할 수 있습니다. 그러나 이 경우 문자를 수동으로 계산해야 할 수도 있습니다.

         1         2         3         4         5         6         7
1234567890123456789012345678901234567890123456789012345678901234567890
PROD   192.168.100.29   windows mail gateway       Active down 

위의 개수로 판단하면 다음과 같이 작동할 수 있습니다.

$ cut -c8-23,52-70 file-fixed.txt
192.168.100.25  Active
192.168.100.26  Active
192.168.100.27  Active
192.168.100.28  Not Active
192.168.100.29  Active down 
192.168.100.30  Active down

적어도 GNU AWK는 고정 너비 필드도 지원하지만 이에 대해 깊이 조사하지는 않았습니다. 바라보다https://www.gnu.org/software/gawk/manual/html_node/Fixed-width-data.html

답변2

먼저 awk는 사용자가 요청한 작업을 수행하고 있다는 점을 분명히 해두겠습니다. 기본적으로 필드를 구분합니다.공백, 관심 있는 열에는 공백 문자가 포함될 수 있으므로 각 공백은 awk에 대한 새 필드를 나타냅니다.

두 개의 임의 문자열 입력이 있는 경우 Linux 명령을 통해 필드를 구문 분석한 후 이를 분리하기가 어렵습니다 column. 내 경험상 Python과 같은 보다 강력한 프로그래밍 언어를 호출하는 것이 더 좋습니다. 저는 Python CSV 라이브러리에 고정 너비 필드의 형식을 추론하는 도구가 있다고 생각합니다.

"활성" "비활성" "아래" 옵션만 사용하도록 마지막 필드를 변경할 수 있는 경우 다음을 사용할 수 있습니다.

awk '{ print $2 $NF }' Inputfile

$NF이는 "필드 수"를 의미하며 마지막 필드를 선택하는 것과 같습니다.

그러나 데이터의 마지막 열에는 공백이 포함될 수도 있고 포함되지 않을 수도 있어 이 구문이 깨집니다.

또는 다른 사람들이 지적했듯이 필드가 탭으로 구분된 경우 다음을 사용할 수 있습니다.

awk -F $'\t' '{ print $2 $4 }' Inputfile

플래그는 탭 문자인 -F필드 구분 기호를 지정합니다 .$'\t'

그러나 항목이 다음과 같은 경우아니요탭으로 구분되어 있으므로 이 데이터 형식과 관련된 작업을 수행해야 할 수도 있습니다. 형식이 다른 다른 입력 파일이 있는 경우 여전히 오류가 나타날 수 있습니다.

다음은 모든 인스턴스를 사용하는 예입니다.둘 이상필드 구분 기호로 사용되는 공백 문자:

awk -F ' {2,}' '{ print $2 $NF }' Inputfile

이 경우 필드 구분 기호는 정규식입니다. 이는 "두 개 이상의 공백 문자로 구성된 인스턴스"와 동일합니다.

이는 제공한 예에서는 작동하지만 첫 번째 또는 마지막 필드 이외의 필드가 필요한 경우 열 3에 여러 공백이 포함되어 있으면 여전히 문제가 발생할 수 있습니다.

답변3

이 경우 awk를 사용하려면 먼저 "Not Active" 및 "Active down"의 공백을 다른 문자로 바꾸십시오.

sed 's/Not Active/Not_Active/g ; s/Active down/Active_down/g' inputfile

그런 다음 awk를 사용하여 두 번째 및 마지막 필드를 추출합니다.

awk '{print $2,$NF}'

마지막으로 다음 공간을 복원하십시오.

sed 's/_//g'

이 모든 것을 종합하면 최종 명령은 다음과 같습니다.

sed 's/Not Active/Not_Active/g ; s/inputfile down/Active_down/g' active | awk '{print $2,$NF}' | sed 's/_/ /g'

관련 정보