2つのファイル間の文字列値を置き換える

2つのファイル間の文字列値を置き換える

ファイル1のフォルマント[1]の周波数と帯域幅をファイル2のフォルマント[1]の周波数と帯域幅に変更したいと思います。この交換はnフレームに対して行う必要があります。 Unixスクリプトでこれを行う方法は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の行を印刷しますmodmod7行目から19行ごとに計算すると、フレームごとにフォルマント[1]データに到達します。

答え2

これはやや高いレベルのアプローチです。これはスクリプトの代わりにシェルスクリプトを使用しますawk。ソリューションはawk非常にエレガントです。私はこれを代替例として提示します。

前提:各ファイルには同じ数のフォルマントがあり、フォルマントの順序は同じです。 file1 の最初のフォルマントは file2 の最初のフォルマントを置き換え、2 番目の形式は 2 番目の形式を置き換える式です。フォルマントには可変数の行を含めることができ、フォルマントあたりの行数はファイルごとに異なる場合があります。

スクリプトはこの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

関連情報