루프를 사용하여 가변 패턴 사이의 선을 추출하는 방법

루프를 사용하여 가변 패턴 사이의 선을 추출하는 방법

다음과 같은 패턴 목록이 포함된 CSV 파일이 있습니다.

파일 1:

aaa;bbb      
ccc;ddd
eee;fff
...

파일 2:

aaa2222222222222222
3333333333333333333
4444444444444444444
bbb555555555555555
8888888888888888888
ccc5555555555555555
5555555555555555555
0000000000000000000
ddd6666666666666666

명령에서 파일 1의 각 줄에 2개의 패턴(예: & )을 사용하여 파일 2의 일치하는 패턴 사이의 줄을 일치시키고 인쇄하고 출력을 저장한 다음 명령을 다음 패턴 쌍으로 바꿔 반복하려면 어떻게 해야 합니까 aaa? 프로세스?bbbsed -n '/aaa/,/bbb/p'

내 예상 결과는

333333333333333         
444444444444444   

aaa& 사이에 줄이 있으므로 새 파일에 저장합니다 .bbb

cccddd그런 다음 루프를 사용하여 & 등 사이의 다음 행 집합을 찾습니다 .

답변1

file1 또는 file2에 지정된 겹치거나 중첩된 범위 또는 반복되는 시작/끝 문자열이 없다고 가정하면 이것이 아마도 당신이 찾고 있는 것일 것입니다.

$ cat tst.awk
BEGIN { FS=";" }

NR==FNR {
    begs2ends[$1] = $2
    next
}

end == "" {
    for ( beg in begs2ends ) {
        if ( index($0,beg) == 1 ) {
            end = begs2ends[beg]
            close(out)
            out = "out" (++cnt) ".txt"
            break
        }
    }
    next
}

{
    if ( index($0,end) == 1 ) {
        end = ""
    }
    else {
        print $0 " > " out
    }
}

.

$ awk -f tst.awk file1 file2
3333333333333333333 > out1.txt
4444444444444444444 > out1.txt
5555555555555555555 > out2.txt
0000000000000000000 > out2.txt

초기 테스트를 완료한 후 print $0 " > " out실제로 별도의 출력 파일을 생성하도록 변경합니다.print > out

답변2

나는 하나의 프로세스만 필요하기 때문에 awk를 좋아합니다. sed를 사용하려면 비효율적인 쉘 루프와 여러 sed 명령이 필요할 수 있습니다.

awk -F ';' '
    NR==FNR{        #For the first file given as an argument
        k++         #Increment k
        pat1[k]=$1  #Add 1st field (before ;) to pat1 array
        pat2[k]=$2  #Add 2nd field (after ;) to pat2 array
        next        #Start new cycle with the next line
    }

    {
        for (i=1;i<=k;i++){
            if ($0~pat2[i]){flag[i]=0}           #If line has terminating pattern
            if (flag[i]){print>(pat1[i]pat2[i])} #If flag=1, print this line to a file
            if ($0~pat1[i]){flag[i]=1}           #If line has starting pattern
        }
    }
' patterns.csv input

매개변수를 반대로 바꾸지 않도록 주의하십시오. 먼저 스키마 파일, 그 다음 입력 파일입니다.

입력 예:

aaa2
3333
4444
bbb5
8888
ccc5
0000
aaa7
7777
bbb7
ddd6

다음 내용으로 두 개의 파일을 만듭니다.

$ cat aaabbb
3333
4444
7777
$ cat cccddd
0000
aaa7
7777
bbb7

답변3

Gnu sed를 사용하여 file1의 내용에서 sed 코드를 동적으로 준비한 다음 생성된 코드를 file2에 적용합니다. 이러한 파일은 자동으로 생성됩니다.

sed -Ee 's|;|/,/|' \
     -e 's|(.).*(.)|/&/{\n\t//!w FILE_\1\2\n}|' file1 \
|  sed -nf - file2
more FILE_?? 

답변4

file2content="$( < file2 )";
while read p;do 
    ((${#p}))&&sed -n "/${p%;*}/,/${p##*;}/p" <<< "${file2content}"|grep -v "^${p%;*}\|^${p##*;}" > "${p%;*}_${p##*;}"; 
done <file1

관련 정보