행을 열로 변환

행을 열로 변환

행 블록이 빈 행으로 구분되어 있고 행을 열로 변환해야 하는 이와 같은 입력이 있습니다.

입력하다

HEAD1
IF
FI
GH

HEAD2
PU
GT

HEAD3
FG
DF
YT
GU

다음과 같이 인쇄해야 합니다.

HEAD1 IF FI GH
HEAD2 PU GT
HEAD3 FG DF YT GU

답변1

$ awk -v RS='' '{ $1 = $1; print }' file
HEAD1 IF FI GH
HEAD2 PU GT
HEAD3 FG DF YT GU

RS입력 레코드 구분 기호가 기본 줄 바꿈 문자 대신 공백인 경우 , awk입력은 입력에 나타나는 두 개 이상의 연속 줄 바꿈을 기반으로 레코드로 나누어집니다. 즉, 하나 이상의 빈 줄이 레코드의 끝을 표시하는 것으로 처리됩니다. 이를 종종 awk"단락 모드"라고 합니다.

그런 다음 코드는 첫 번째 필드를 자신으로 설정합니다. 이는 무작동 작업처럼 보일 수 있지만 이로 인해 awk현재 출력 레코드가 다시 작성됩니다. ORS(출력 레코드 구분 기호) 및 (출력 필드 구분 기호)에 대한 기본값이 사용되므로 OFS(각각 줄 바꿈 및 공백) 레코드가 인쇄될 때 모든 필드는 사이에 공백이 있고 줄 바꿈으로 끝나는 한 줄에 인쇄됩니다. .

값을 수정하여 다른 문자열이나 문자로 구분된 필드를 가져올 수 있습니다 OFS.

$ awk -v RS='' -v OFS='\t' '{ $1 = $1; print }' file
HEAD1   IF      FI      GH
HEAD2   PU      GT
HEAD3   FG      DF      YT      GU
$ awk -v RS='' -v OFS=',' '{ $1 = $1; print }' file
HEAD1,IF,FI,GH
HEAD2,PU,GT
HEAD3,FG,DF,YT,GU
$ awk -v RS='' -v OFS='::' '{ $1 = $1; print }' file
HEAD1::IF::FI::GH
HEAD2::PU::GT
HEAD3::FG::DF::YT::GU

이 코드는 무조건 기본 작업을 호출하여 후행 으로 인해 현재 레코드가 인쇄되도록 awk단축될 수 있습니다 . 이는 현재 레코드를 무조건 인쇄하는 매우 일반적인 방법입니다.{ $1 = $1 }; 11


대신 사용하십시오 sed:

$ sed -e '/./ { H; $!d; }' -e 'x; y/\n/ /; s/.//' file
HEAD1 IF FI GH
HEAD2 PU GT
HEAD3 FG DF YT GU

H줄에 내용이 포함되어 있으면 현재 줄을 예약된 공간에 추가합니다. 줄 바꿈을 구분하여 예약된 공간에 줄이 추가됩니다. 이것이 입력의 마지막 줄이 아니면 패턴 공간은 버려지고 d다음 입력 줄부터 즉시 시작됩니다.

현재 줄이 비어 있으면 예약된 공간을 다음으로 바꾸고 x(패턴 공간이 비어 있으므로 예약된 공간을 지우는 효과도 있음) 모든 줄 바꿈을 공백으로 바꾸고 첫 번째 문자를 제거합니다(추가 문자가 됨). 공백 문자).

답변2

awk단락 모드에서:

awk -v RS= -v FS='\n' -v OFS=' ' '{
        for (i=1;i<=NF;i++) {
        printf "%s%s", $i, (i<NF ? OFS : ORS)
    }
}' file
HEAD1 IF FI GH
HEAD2 PU GT
HEAD3 FG DF YT GU
  • RS=이 설정 후에 RS는 입력 레코드가 빈 줄로 구분됩니다.
  • FS='\n'이렇게 하면 각 단락의 각 줄을 레코드 필드로 처리할 수 있습니다.
  • for모든 필드를 반복하고 printf조건식으로 인쇄합니다 ternary expression. exp1이 i<NFtrue를 반환 하면 OFS실행하고, 그렇지 않으면 ORS실행합니다.

관련 정보