awk의 동적 정규 표현식
Nov 22 2020
다음과 같은 텍스트 파일이 있습니다.
1.txt
AA;00000;
BB;11111;
GG;22222;
2.txt
KK;WW;55555;11111;
KK;FF;ZZ;11111;
KK;RR;YY;11111;
이 3.txt 출력을 생성합니다.
AA;00000;
BB;11111;KK;WW;55555;FF;ZZ;RR;YY
GG;22222;
이 .awk 스크립트로 (Windows에서 cmd와 함께 사용)
#!/usr/bin/awk -f
NR != FNR {
exit
}
{
printf "%s", $0 } /^BB/ { o = "" while (getline tmp < ARGV[2]) { n = split (tmp,arr,";") for (i=1; i<=n; i++) if(!match($0,arr[i]) && !match(o,arr[i]))
o=o arr[i]";"
}
printf "%s", o
}
{
print ""
}
사용법은 awk -f script.awk 1.txt 2.txt
괜찮은 것 같지만이 상황을 고려하십시오
1.txt
AA;BB;
2.txt
CC;DD;BB;AA;
이제 이런 식으로 교체
AA
로 교체 d(2)
BB
로 대체 http://a.o/f/i.p?t=1
CC
로 대체 Link
DD
와A_x-y.7z
스크립트는 3.txt를 생성 할 수 없습니다.
AA;BB;CC;DD;
또는 대체 된 텍스트를 사용하면이 3.txt 텍스트 출력을 생성 할 수 없습니다.
d(2);http://a.o/f/i.p?t=1;Link;A_x-y.7z;
스크립트가 그런 방식으로 작동하기 때문에 AA
, 같은 중복 필드 BB
가 3.txt 출력에서 제거 된 것을 볼 수 있습니다 .
나는 그것이이 함께 할 수있다 생각 (...)
에 그룹화 정규식으로 간주되는 match()
첫 번째 매개 변수는 정규식으로하고 전달하여 $0
동적 정규 표현식에서 * 모두 "로 처리됩니다 O를 awk
말하다
답변
1 EdMorton Nov 22 2020 at 23:36
$ cat tst.awk BEGIN { FS=OFS=";" } { key = $(NF-1) }
NR == FNR {
for (i=1; i<(NF-1); i++) {
if ( !seen[key,$i]++ ) { map[key] = (key in map ? map[key] OFS : "") $i
}
}
next
}
{ print $0 map[key] }
$ awk -f tst.awk 2.txt 1.txt
AA;00000;
BB;11111;KK;WW;55555;FF;ZZ;RR;YY
GG;22222;
위의 내용은 배열 인덱스의 해시 조회에서 리터럴 문자열을 사용하므로 입력에 어떤 문자가 있는지는 신경 쓰지 않습니다. 당신이 리터럴 문자열은 다음 정규 표현식 함수 또는 연산자를 (예를 들어, 사용하지 않는 사용자의 입력을 처리하려면 match()
, ~
, sub()
그것에), 단지 사용 문자열 함수 / 연산자를 (예를 들어 index()
, ==
, substr()
, in
).