두 파일 사이의 문자열 값 바꾸기

두 파일 사이의 문자열 값 바꾸기

파일 1의 포먼트 [1]의 주파수와 대역폭을 파일 2의 포먼트 [1]의 주파수와 대역폭으로 바꾸고 싶습니다. 이 교체는 n 프레임에 대해 수행되어야 합니다. 유닉스 스크립트를 통해 이를 수행하는 방법은 1000프레임입니다. 도와주세요.

파일 1:

frames []: 
    frames [1]:
        intensity = 0.006356559616564358 
        nFormants = 5 
        formant []: 
            formant [1]:
                frequency = 403.06628436252515 
                bandwidth = 160.21467462436982 
            formant [2]:
                frequency = 1507.54711702621 
                bandwidth = 519.232413949129 
            formant [3]:
                frequency = 2577.174907989416 
                bandwidth = 1535.5870557191413 
            formant [4]:
                frequency = 3764.624274996511 
                bandwidth = 209.668143917888 
            formant [5]:
                frequency = 4823.479775451361 
                bandwidth = 357.147764183363 
    frames [2]:
        intensity = 0.007108941260004555 
        nFormants = 5 
        formant []: 
            formant [1]:
                frequency = 420.7936179207871 
                bandwidth = 156.6697641580339 
            formant [2]:
                frequency = 1434.5440278308877 
                bandwidth = 377.849704303127 
            formant [3]:
                frequency = 2620.589627797242 
                bandwidth = 1336.5922989596068 
            formant [4]:
                frequency = 3772.337062263397 
                bandwidth = 248.2627364453784 
            formant [5]:
                frequency = 4748.112746186265 
                bandwidth = 244.23733261870277 

파일 2:

frames []: 
    frames [1]:
        intensity = 0.306356559616564358 
        nFormants = 5 
        formant []: 
            formant [1]:
                frequency = 203.06628436252515 
                bandwidth = 150.21467462436982 
            formant [2]:
                frequency = 1607.54711702621 
                bandwidth = 629.232413949129 
            formant [3]:
                frequency = 3577.174907989416 
                bandwidth = 3535.5870557191413 
            formant [4]:
                frequency = 4764.624274996511 
                bandwidth = 309.668143917888 
            formant [5]:
                frequency = 5823.479775451361 
                bandwidth = 457.147764183363 
    frames [2]:
        intensity = 0.007108941260004555 
        nFormants = 5 
        formant []: 
            formant [1]:
                frequency = 320.7936179207871 
                bandwidth = 156.6697641580339 
            formant [2]:
                frequency = 1334.5440278308877 
                bandwidth = 377.849704303127 
            formant [3]:
                frequency = 2520.589627797242 
                bandwidth = 1336.5922989596068 
            formant [4]:
                frequency = 4472.337062263397 
                bandwidth = 248.2627364453784 
            formant [5]:
                frequency = 4648.112746186265 
                bandwidth = 244.23733261870277 

답변1

awk oneliner (주어진 가정에 기초):

awk '{lines[FILENAME,FNR]=$0;last=FNR}END{for(i=1;i<=last;i++){mod=(i-7+19)%19;print(lines[mod>1?"file1":"file2",i])}}' file1 file2

분석은 다음과 같습니다.

{
    lines[FILENAME,FNR]=$0;
    last=FNR
}

위의 내용은 각 파일의 행을 저장합니다. 또한 FNR(파일 레코드 번호)을 저장하여 파일에 몇 줄이 있는지 알 수 있습니다.

END {
    for(i=1;i<=last;i++) {
        mod=(i-7+19)%19;
        print(lines[mod>1?"file1":"file2",i])
    }
}

위의 코드는 각 줄을 반복하고 값에 따라 파일 1 또는 2의 줄을 인쇄합니다 mod. mod7번째 라인부터 19라인마다 계산하면 매 프레임마다 포먼트[1] 데이터에 도달하게 됩니다.

답변2

이는 약간 더 높은 수준의 접근 방식입니다. 이는 스크립트 대신 쉘 스크립트를 사용합니다 awk. 솔루션 은 awk매우 우아합니다. 나는 이것을 대안적인 예로 제시합니다.

가정: 각 파일에는 동일한 수의 포먼트가 있으며 포먼트의 순서는 동일합니다. file1의 첫 번째 포먼트는 file2의 첫 번째 포먼트를 대체하고, 두 번째 형식은 두 번째 형식을 대체하는 식입니다. 포먼트에는 가변 개수의 라인이 포함될 수 있으며 포먼트당 라인 수는 각 파일마다 다를 수 있습니다.

스크립트는 이 csplit명령을 사용하여 각 파일을 여러 부분으로 분할합니다. 홀수 부분에는 formant[1]s가 포함되고 짝수 부분에는 다른 모든 내용이 포함됩니다.

두 파일을 분할한 후 file2에서 홀수 부분을 모두 제거하고 file1에서 짝수 부분을 모두 제거합니다. 그런 다음 cat나머지 파일을 함께 결합하여 최종 출력을 생성합니다.

csplit파일 번호를 끝에 추가하도록 출력 파일 이름 형식을 수정했기 때문에 두 원본 파일은 동일한 디렉터리로 분할되며 셸의 패턴 일치 및 정렬을 활용하여 해당 파일을 삭제하고 나머지 부분을 올바른 순서로 재조립합니다. .

#!/bin/sh

USAGE="
    $0: Usage: $0 file1 file2
    $0 replaces formant[1]'s in file1 with formant[1]'s from file2
    $0 prints the new version of file1 on standard output
"

TMP=tmp$$
mkdir $TMP

for i in 2 1
do
    csplit --quiet --prefix="$TMP/" --suffix-format="%09d-$i" "${1:?$USAGE}" \
         '/formant \[[12]\]/' '{*}'
    shift
done

rm $TMP/*[13579]-2
rm $TMP/*[02468]-1
cat $TMP/*
rm -r $TMP

그러면 다음과 동일한 출력이 생성됩니다.이 다른 답변

답변3

awk '
    {
        getline a <file2
        if(prn)
            print a
        else
            print
    }
    /formant \[1\]/{
        prn = 1
    }
    /bandwidth/{
        prn = 0
    }
    ' file1

주파수를 얻기 위해 file1과 file2의 서로 다른 수의 포먼트에 대해:

awk '
    BEGIN{
        pattern = "formant \\[1\\]"
    }
    prn{
        prn = 0
        while($0 !~ pattern)
            getline <file2
        getline <file2
    }
    $0 ~ pattern{
        prn = 1
    }
    1
    ' file1

관련 정보