두 번째 열을 분리하는 awk 명령

두 번째 열을 분리하는 awk 명령

다음 형식의 데이터가 포함된 파일이 있습니다.

Item1|keys,books,helmet,handle,
Item2|Bike,
Item3
Item4|Tyre,brakes,headlight,clamps,rollergrip,
Item5|Nails,hammers,

위의 데이터를 다음 형식으로 변환하고 싶습니다.

Item1|keys
Item1|books
Item1|helmet
Item1|handle
Item2|Bike
Item3
Item4|Tyre
Item4|brakes
Item4|headlight
Item4|clamps
Item4|rollergrip
Item5|Nails
Item5|hammers

나는 cut 명령을 사용하여 이를 달성하려고 노력하고 있으며 비록 잘 작동하지만 awk 명령을 사용하여 이를 달성할 수 있는지 알고 싶습니다. 왜냐하면 입력 파일 크기가 커지면 문제가 되기 때문입니다.

답변1

sed -e 's/,$//' -e '/^[^|]*$/s/$/|/' file.in |
awk -F'[|,]' -vOFS='|' '{ for (i = 2; i <= NF; ++i) { print $1, $i } }'

입력 데이터에 대해 sed일부 전처리를 수행합니다. -e 's/,$//'각 줄 끝에 있는 쉼표( )를 제거 하고 -e '/^[^|]*$/s/$/|/'줄에 파이프 기호가 없으면 끝에 1( )을 추가합니다.

샘플 데이터는 필터에 의해 다음과 같이 변환됩니다 sed.

Item1|keys,books,helmet,handle
Item2|Bike
Item3|
Item4|Tyre,brakes,headlight,clamps,rollergrip
Item5|Nails,hammers

스크립트 awk는 이 정보를 받아들이고 각 줄을 -F'[|,]'파이프 기호나 쉼표( )로 구분된 필드 집합으로 해석합니다. 각 입력 행에 대해 첫 번째 필드를 다른 모든 필드와 반복적으로 쌍을 이루어 출력합니다. 출력의 각 필드 쌍은 -vOFS='|'파이프 기호( )로 구분됩니다.

밝혀지다

Item1|keys
Item1|books
Item1|helmet
Item1|handle
Item2|Bike
Item3|
Item4|Tyre
Item4|brakes
Item4|headlight
Item4|clamps
Item4|rollergrip
Item5|Nails
Item5|hammers

답변2

해결책:

awk -F'|' 'NF>1 && $2~/[^,]+,[^,]*/{ 
           len=split($2,a,","); 
           for(i=1;i<=len;i++) { 
               if(a[i]!="") print $1,a[i] 
           } 
           next }1' OFS='|' file

산출:

Item1|keys
Item1|books
Item1|helmet
Item1|handle
Item2|Bike
Item3
Item4|Tyre
Item4|brakes
Item4|headlight
Item4|clamps
Item4|rollergrip
Item5|Nails
Item5|hammers

세부 사항:

  • -F'|'- 필드 구분 기호

  • NF>1 && $2~/[^,]+,[^,]*/- 두 번째 필드 내의 값이 쉼표로 구분되는 필드를 2개 이상 고려하세요.

  • len=split($2,a,",")a-두 번째 필드를 구분 기호로 배열로 분할합니다 ,. 변수 len는 배열 크기(블록 수)로 할당됩니다.

  • for(i=1;i<=len;i++) "를 통해 반복조각"

  • if(a[i]!="") print $1,a[i]- null 값을 제외한 모든 관련 시퀀스를 인쇄합니다.

답변3

다른 awk버전

  • |필드 구분 기호를 또는 로 설정,
  • 레코드에 필드가 2개 미만인 경우 있는 그대로 인쇄합니다.
  • else는 모든 필드 2를 반복하여 NF-1인쇄 $1하고 (이것은 후행 쉼표로 인한 $inull을 건너뜁니다.$NF

$ awk 'NF<2 ; {for (i=2;i<NF;i++) print $1,$i}' FS='[|,]' OFS='|' file
Item1|keys
Item1|books
Item1|helmet
Item1|handle
Item2|Bike
Item3
Item4|Tyre
Item4|brakes
Item4|headlight
Item4|clamps
Item4|rollergrip
Item5|Nails
Item5|hammers

관련 정보