정규식으로 변수를 awk

정규식으로 변수를 awk

질문은 정말 간단합니다. 질문을 모두 읽었지만 아직 답을 할 수 없습니다! 다음과 같은 일반 파일이 있습니다.

$cat file1.txt
ALA
AJD
KSF

그리고 awk가 각 값을 정규식으로 사용하여 다른 파일의 줄을 다른 파일로 인쇄하기를 원합니다.

$cat file2.txt
name,st,ed,le
ALA,10,12,12
ALA,2,5,4
ALA,6,5,8
AJD,5,8,7
KSF,5,8,7

그래서 내 스크립트는

while read p;
awk -F"," 'NR==1{print $0}' file2.txt > $p.csv
awk -F"," '/$p/{print $0}' file2.txt >> $p.csv
done <file1.txt

원하는 출력은 다음과 같습니다.

$cat ALA.csv
name,st,ed,le
ALA,10,12,12
ALA,2,5,4
ALA,6,5,8
$cat AJD.csv
name,st,ed,le
AJD,5,8,7
$cat KSF.csv
name,st,ed,le
KSF,5,8,7

불행히도 각 파일에는 헤더만 인쇄됩니다. $p를 대체하여 file1.txt의 각 값을 수동으로 입력했는데 완벽하게 작동합니다. 그래서 문제는 $p 변수가 잘 해석되지 않았다는 점이라고 생각합니다. 나는 따옴표를 사용하여 이중으로 간단하게 시도했습니다. 또한 제가 찾은 다양한 제안을 시도했지만 아무 것도 작동하지 않는 것 같습니다!

답변1

당신이 할 수 있는 동안:

awk "/$p/" file2.txt > "$p.csv"

그것은 껍질을 가지고 있다는 것입니다확장하다$p에 전달된 코드의 셸 변수 내용은 나쁜 습관이며 기본적으로 명령 주입 취약점에 해당합니다(예: like awk값의 경우 ). 가장 좋은 방법은 쉘 변수를 그대로 awk에 전달하고 정규식 일치를 위해 awk의 연산자를 사용하는 것입니다. 가장 좋은 방법은 환경 변수와 의 특수 배열을 사용하는 것입니다.$p^/{system("reboot");/~awkENVIRON

export P
while IFS= read -r P; do
  awk 'NR == 1 || $0 ~ ENVIRON["P"]' < file2.txt > "$P.csv"
done < file1.txt

그러나 여기서는 쉘 루프를 피하고 파일에서 한 번의 패스만 수행할 수 있습니다.

awk 'NR == FNR {files[$0]; next}
     FNR == 1 {for (f in files) print > f ".csv"; next}
     {
       for (f in files)
         if ($0 ~ f) print > f ".csv"
     }' file1.txt file2.txt

관련 정보