替换两个文件之间的字符串值

替换两个文件之间的字符串值

我想用文件 2 共振峰 [1] 的频率和带宽替换文件 1 的共振峰 [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 中的行modmod计算为每 19 行,从第 7 行开始,每帧都会达到共振峰 [1] 数据。

答案2

这是一个稍微更高层次的方法。这使用 shell 脚本而不是awk脚本。解决awk方案非常优雅。我提供这个作为替代示例。

假设:每个文件中有相同数量的共振峰,并且共振峰的顺序相同。 file1 中的第一个共振峰替换 file2 中的第一个共振峰,第二格式替换第二格式,等等。共振峰可以包含可变数量的行,并且每个文件中每个共振峰的行数可以不同。

该脚本使用该csplit命令将每个文件拆分为多个部分。奇数部分包含formant[1]s,偶数部分包含其他所有内容。

拆分两个文件后,从 file2 中删除所有奇数部分,并从 file1 中删除所有偶数部分。然后将cat剩余的文件组合在一起以产生最终的输出。

由于我们修改了csplit输出文件名格式,将文件编号附加到末尾,因此两个原始文件将被拆分到同一目录中,并且我们利用 shell 的模式匹配和排序来删除相应的文件并重新组装剩余部分以正确的顺序。

#!/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

相关内容