根据字符串列表和相应替换列表替换文件中的字符串

Rob*_*hoy 5 sed awk perl text-processing

我正在尝试替换 a 中的字符串file A

Hello Peter, how is your dad? where is mom? 
Run Code Online (Sandbox Code Playgroud)

要替换的字符串在file B

Peter
dad
mom
Run Code Online (Sandbox Code Playgroud)

和他们相应的替代品在file C

John
wife
grandpa
Run Code Online (Sandbox Code Playgroud)

预期结果:

Hello John, how is your wife? where is grandpa?
Run Code Online (Sandbox Code Playgroud)

我可以编辑file Afile B使用 in 中相应行中的值替换 in中的值file C吗?

到目前为止我做了什么:

 cat 1.txt | sed -e "s/$(sed 's:/:\\/:g' 2.txt)/$(sed 's:/:\\/:g' 3.txt)/" > 4.txt
Run Code Online (Sandbox Code Playgroud)

如果file B& 中只有file C一行,它会起作用,如果有多于一行,它将不起作用。

don*_*sti 9

最简单的方法sed是处理这两个列表并将它们转换为脚本文件,例如

s/line1-from-fileB/line1-from-fileC/g
s/line2-from-fileB/line2-from-fileC/g
....................................
s/lineN-from-fileB/lineN-from-fileC/g
Run Code Online (Sandbox Code Playgroud)

sed然后将执行,编辑fileA。的适当的方式是处理LHS/RHS第一和逃脱这些线路可能出现的任何特殊字符,然后加入LHSRHS加入s,分隔符/g(例如用paste)和管道将结果sed

paste -ds///g /dev/null /dev/null \
<(sed 's|[[\.*^$/]|\\&|g' fileB) <(sed 's|[\&/]|\\&|g' fileC) \
/dev/null /dev/null | sed -f - fileA
Run Code Online (Sandbox Code Playgroud)

所以它是:一个paste和三个seds 将只处理每个文件一次,而不管行数如何。
这假设您的 shell 支持进程替换,并且您sed可以从stdin读取脚本文件。此外,它不会就地编辑(我忽略了开关,因为它不受所有s支持)-ised


inf*_*era 0

我创建的解决方案不是很短,但足够简单,非常易读。除非你的任务是用 sed 完成整个事情...?

 #!/usr/bin/bash

 cp A.txt D.txt

 x=1
 length=$(wc -l B.txt | sed 's/\ .*//g')

 until [ $x -eq $length ]; do

    Bx=$(awk "NR==$x" B.txt)
    Cx=$(awk "NR==$x" C.txt)

    sed -i "s/$Bx/$Cx/g" D.txt

    x=$(($x+1))

 done

 rm -f ./sed*
Run Code Online (Sandbox Code Playgroud)

请注意,如果 B.txt 比 C.txt 长,则此脚本会创建大量垃圾文件,反之亦然(没有测试那么远)