AWK를 사용하여 관리되는 4줄 문단 세트

AWK를 사용하여 관리되는 4줄 문단 세트

4줄의 여러 단락(2000개 이상)으로 구성된 파일이 있습니다. 아래 예와 같이 각 단락에 대해 대괄호 사이의 내용을 일치시켜야 합니다.

그래서 각 단락마다,

  • 항목은 처음 두 행입니다.
  • 세 번째 줄의 경우 대괄호 사이의 현재 내용이 두 번째 줄의 대괄호 사이의 내용으로 대체됩니다.
  • 네 번째 줄에서는 대괄호 사이의 현재 내용이 첫 번째 행의 대괄호 사이에 있는 내용으로 대체됩니다.

나는 그것이 충분히 명확하기를 바랍니다.

--입력하다--

A1 [A3 A4 A5] A2
B1 [B3 B4 B5] B2
C1 [C3 C4] C2
D1 [D3 D4] D2

E1 [E3 E4 E5] E2
F1 [F3 F4 F5] F2
G1 [G3 G4] G2
H1 [H3 H4] H2

--산출--

A1 [A3 A4 A5] A2
B1 [B3 B4 B5] B2
C1 [B3 B4 B5] C2
D1 [A3 A4 A5] D2

E1 [E3 E4 E5] E2
F1 [F3 F4 F5] F2
G1 [F3 F4 F5] G2
H1 [E3 E4 E5] H2

해결책이 있나요? awk와 gsub를 사용하는 것 같지만 그게 문제입니다.

답변1

awk -F[][] -vOFS= '++i==1 {a=$2} i==2 {b=$2} i==3 {$2="[" b "]"} i==4 {$2="[" a "]"} !NF {i=0} 1' input.txt

대괄호를 필드 구분 기호로 사용하고 대체 소스/대상은 $2.

각 줄마다 이를 증가시키고 i단락 사이에서 0으로 재설정합니다. (1~4)의 값은 i무엇을 해야 할지 알려줍니다 $2.

답변2

$ cat tst.awk
match($0,/\[.*]/) {
    idx = (NR - 1) % 5 + 1
    sect[idx] = substr($0,RSTART,RLENGTH)
    if ( idx == 3 ) {
        $0 = $1 OFS sect[2] OFS $NF
    }
    else if ( idx == 4 ) {
        $0 = $1 OFS sect[1] OFS $NF
    }
}
{ print }

$ awk -f tst.awk file
A1 [A3 A4 A5] A2
B1 [B3 B4 B5] B2
C1 [B3 B4 B5] C2
D1 [A3 A4 A5] D2

E1 [E3 E4 E5] E2
F1 [F3 F4 F5] F2
G1 [F3 F4 F5] G2
H1 [E3 E4 E5] H2

위의 코드는 문자열 대체를 수행하므로 대괄호 안의 부분에 정규식 메타 문자나 역참조가 포함되어 있어도 작동합니다.

답변3

대괄호 사이에 정규식 특수 문자가 없다고 가정하는 GNU awk:

$ gawk -vRS= '
  BEGIN{OFS=FS="\n"}
  match($1,/\[[^]]*\]/,x) && match($2,/\[[^]]*\]/,y) {
    sub(/\[[^]]*\]/,y[0],$3);
    sub(/\[[^]]*\]/,x[0],$4);
    printf "%s%s", $0, RT
  }
  ' file
A1 [A3 A4 A5] A2
B1 [B3 B4 B5] B2
C1 [B3 B4 B5] C2
D1 [A3 A4 A5] D2

E1 [E3 E4 E5] E2
F1 [F3 F4 F5] F2
G1 [F3 F4 F5] G2
H1 [E3 E4 E5] H2

교체를 위해 등을 사용해야 한다는 점을 제외하면 GNU가 아닌 awk에서도 본질적으로 가능하며 다음을 사용하여 원래 입력 레코드 구분 기호를 복원 substr($1,RSTART,RLENGTH)할 수 없습니다 .RT

awk '
  BEGIN{RS=""; ORS="\n\n"; OFS=FS="\n"}
  match($1,/\[[^]]*\]/) {x = substr($1,RSTART,RLENGTH)}
  match($2,/\[[^]]*\]/) {y = substr($2,RSTART,RLENGTH)}
  {
    sub(/\[[^]]*\]/,y,$3);
    sub(/\[[^]]*\]/,x,$4);
    print
  }
  ' file

답변4

perl -00pe 's/(.*)(\[.*\])(.*\n)
              (.*)(\[.*\])(.*\n)
              (.*)(\[.*\])(.*\n)
              (.*)(\[.*\])(.*\n)
             /$1$2$3$4$5$6$7$5$9$10$2$12/x' input1

perl -00pe-- 각 단락마다.

RE의 각 줄은 입력 단락 줄과 일치하며 관련 섹션에서 구분됩니다. 교체 그룹 내에서는 부품을 다시 주문하기만 하면 됩니다.

혼란을 드려 죄송합니다...

관련 정보