将字符串替换为另一个文件中的行范围,包括替换时修改行范围

将字符串替换为另一个文件中的行范围,包括替换时修改行范围

我有两个代码文件,第一个 (File1) 包括要包含的几行文本,第二个 (File2) 包括将被第一个文件中的一系列行替换的字符串。当第一个文件中包含的行包含在第二个文件中时,还需要将以下字符串附加到每行(不包括引号):“ & ”。此外,需要在输出文件 (File3) 中替换对第一个文件 (File1) 中某些字符串的搜索和替换。下面包含前两个文件的示例。

文件1

A A
B B
C C
D D
N 1 & 1 \\
Me 2 & 2 \\
Sd 3 & 3 \\
Dian 4 & 4 \\
E E
F F
G G
H H

文件2

D D
C C
B B
A A
str_text1
H H
G G
F F
E E

下面的示例是我希望新的输出文件(File3)具有的内容。必须确保 File1 和 File2 不被覆盖,并且所有内容都必须重组到新文件 File3 中。

文件3

D D
C C
B B
A A
 & N 1 & 1 \\
 & $\m$ 2 & 2 \\
 & $\sig$ 3 & 3 \\
 & $\dian{x}$ 4 & 4 \\
H H
G G
F F
E E

我希望这是 shell 脚本中的一个行,下面是我到目前为止所拥有的一个示例。我不知道如何将最后一次替换到同一个内衬中,但是作为第二个内衬,它非常简单。如果这些可以结合起来,我将不胜感激。

代码1

sed -e 's/str_text1/ \& $(sed -n 5,8p File1.txt)/' \
    < File2.txt > File3.txt

代码1输出* 无法包含行。使用双引号会导致错误:sed: -e expression #1, char 18: unterminated `s' command

D D
C C
B B
A A
 & $(sed -n 5,8p File1.txt)
H H
G G
F F
E E

代码2易于搜索和替换,并且按原样工作正常。这将替换新 File3 文件中 File1 第一列中的一些字符串。

    sed -i -e 's/Me/$\m$/g' \
        -i -e 's/Sd/$\sig$/g' \
        -i -e 's/Dian/$\dian{x}$/g' \
        File3.txt

答案1

如果我理解正确的话,这里是执行代码 1 和 2 后您正在查看的最终输出:

D D
C C
B B
A A
 & N 1 & 1 \\
 & $\m$ 2 & 2 \\
 & $\sig$ 3 & 3 \\
 & $\dian{x}$ 4 & 4 \\
H H
G G
F F
E E

我建议使用 awk 与 gsub 的一行混合来实现搜索和替换功能并询问。

    #CODE1 : oneliner
    awk -v a="$(awk 'NR==5, NR==8' File1.txt  | sed -ie 's/\\/#/g' | sed -ie 's/&/@/g' | sed 's/^/ @ &/')" '{ gsub(/str_text1/,a); print }' File2.txt > File3.txt
    #CODE2 : oneliner
    sed -i -e 's/Me/$\\\m$/g' -i -e 's/Sd/$\\\sig$/g' -i -e 's/Dian/\$\\\dian{x}$/g' -i -e 's/@/\&/g' -i -e 's/#/\\/g' File3.txt
    cat File3.txt

解释 :

代码1

与此相同sed -n 5,8p File1.txt,但将整个结果放入 awk 变量中,以便 gsub 实用程序接下来使用它awk -v a="$(awk 'NR==5, NR==8' File1.txt)"

我更喜欢使用awk代替sed用于从文本文件中获取行范围awk 'NR==5, NR==8' File1.txt

将分别替换特殊字符 \ 和 &#@;因为对于下一个命令 (awk) \ 和 & 是特殊字符sed -ie 's/\\/#/g' | sed -ie 's/&/@/g'

代替字符串文本1通过变量的内容A gsub(/str_text1/,a); print

代码2:

我已在您的命令中添加了一些内容,以便它将匹配所需的输出sed -i -e 's/Me/$\\\m$/g' -i -e 's/Sd/$\\\sig$/g' -i -e 's/Dian/\$\\\dian{x}$/g'

替换回我们用作转义字符的字符:@-> & ; # -> \sed -i -e 's/@/\&/g' -i -e 's/#/\\/g'

相关内容