AWK는 텍스트 파일에서 경로를 읽습니다.

AWK는 텍스트 파일에서 경로를 읽습니다.

라는 파일이 있습니다경로 복구.txt여기에는 다른 파일에 대한 경로가 포함되어 있습니다.

~에경로 복구.txt:

./a2111oi/sky130_fd_sc_hd__a2111oi_0.txt
./a2111oi/sky130_fd_sc_hd__a2111oi_2.txt
./a2111oi/sky130_fd_sc_hd__a2111oi_4.txt 

각 경로는 아래와 같이 동일한 구조를 가진 다른 텍스트 파일을 가리킵니다.

HEAD
INFO
BEGIN sky130_fd_sc_hd__a2111oi_0
...
...
END BEGIN
END INFO
END HEAD

path_resume.txt에서 각 .txt 파일을 읽으려고 하며 그 사이의 모든 줄을 복사합니다.시작그리고끝이 시작된다출력.txt라는 다른 파일에 증분적으로 저장합니다.

BEGIN sky130_fd_sc_hd__a2111oi_0
...
...
END BEGIN
BEGIN sky130_fd_sc_hd__a2111oi_2
...
...
END BEGIN
BEGIN sky130_fd_sc_hd__a2111oi_4
...
...
END BEGIN

내가 실행할 때 :

awk '{while((getline a < $0)> 0) print a}' path_resume.txt

path_resume.txt의 모든 파일을 올바르게 읽을 수 있지만 원하지 않는 줄을 제거할 수는 없습니다.

내가 실행할 때 :

awk '/BEGIN/{flag=1}/END BEGIN/{flag=0}flag' ./a2111oi/sky130_fd_sc_hd__a2111oi_0.txt
 >> output.txt

원하지 않는 줄을 제거할 수 있지만 파일 경로를 수동으로 전달해야 합니다. 내 목표를 달성하기 위해 이 두 명령을 병합하는 방법을 모르겠습니다. 도움을 주시면 감사하겠습니다.

답변1

루프 내에서 인쇄/인쇄 안 함 플래그를 사용하여 동일한 논리를 구축할 수 있습니다 while(getline). 이 같은:

awk '{ while((getline a < $0) > 0) { 
    if (a ~ /BEGIN/) p=1;
    if (p) print a;
    if (a ~ /END BEGIN/) p=0;
} }' path_resume.txt > output.txt

if여기서 유일한 것은 AWK 스크립트의 최상위 수준에서 수행하는 것처럼 암시적인 조건 대신 명시적인 명령문을 사용해야 한다는 것입니다 .

또는 Bash에서 파일 이름 목록을 배열에 넣고 한 번에 AWK에 전달합니다.

readarray -t filenames < path_resume.txt
awk '/BEGIN/ {p=1}; p; /END BEGIN/ {p=0}' "${filenames[@]}" > output.txt

END BEGIN( 끝 구분자를 인쇄하기 위해 체크 앞에 인쇄 작업을 넣었습니다 .)

답변2

테스트되지 않은 다음과 같은 작업은 awk를 사용하여 원하는 작업을 수행합니다.

awk '
    NR == FNR { ARGV[ARGC++]=$0; next }
    $1 == "BEGIN" { f=1 }
    f
    $0 == "END BEGIN" { f=0 }
' path_resume.txt > output.txt

아니면 약간 더 빠를 수도 있지만http://awk.freeshell.org/AllAboutGetlinegetline이렇게 하면 불필요하거나 잘못된 사용의 함정 에 빠지지 않습니다 .

awk '
    BEGIN {
        file = ARGV[--ARGC]
        while ( (getline line < file) > 0 ) {
            ARGV[ARGC++] = line
        }
    }
    $1 == "BEGIN" { f=1 }
    f
    $0 == "END BEGIN" { f=0 }
' path_resume.txt > output.txt

답변3

파일의 각 줄을 읽기 위해 xargsdouble을 사용하지 않고 텍스트 파일의 모든 경로를 전달할 수 있습니다.awk

xargs awk  '/BEGIN/{flag=1}/END BEGIN/{print;flag=0}flag'  < path_resume.txt > out.txt

나는 당신의 파일을 가정경로 복구.txt모든 경로에 공백을 포함하지 마십시오.

나는 그 줄도 인쇄 awk하곤 했습니다 .{print;flag=0}END BEGIN


경로의 파일 이름에 공백이 포함되어 있으면 다음 명령을 사용할 수 있습니다.

tr '\n' '\0' < path_resume.txt | xargs -0  awk  '/BEGIN/{flag=1}/END BEGIN/{print;print "";flag=0}flag' > out.txt

답변4

이 접근 방식은 어떻습니까? 이것은 약간 게으르지만 작업이 완료될 것입니다. 다음 줄을 읽고 각 줄을 path_resume.txt파일 로 사용합니다.awk

for i in `cat path_resume.txt`; do awk '/BEGIN/{flag=1}/END BEGIN/{flag=0}flag' $i >> output; done

관련 정보