sed和正则表达式:意外替换模式

时间:2018-06-15 19:06:47

标签: regex bash sed

我正在尝试使用一个小的bash脚本使用sed来追加一个字符串,但我似乎无法使它工作。 我想将一个字符串附加到另一个字符串模式:

输入文件中的字符串:

Xabc
Xdef

期望的输出:

XabcZ
XdefZ

这是脚本:

#!/bin/bash
instring="$2"
sed -r "s/${instring}/${instring}Z/g" $1

其中$ 1是文件名,$ 2是我要找的字符串模式

然后我运行脚本:

bash script.test.sh test.txt X

输出:

XZabc
XZdef

正如所料。 但如果我使用正则表达式:

bash script.test.sh test.txt X...

我得到的只是:

X...Z
X...Z

显然,在命令的替换部分中没有正确读取它。如果我使用X [a-z09](但我的字符串中可能有“_”,我想要包括那些),这就是Smae。我看了几个以前类似的主题,但我似乎无法正确实现任何解决方案(忍受新手......)。谢谢你的帮助。

编辑:在收到Glenn Jackman(已接受的解决方案)和RavinderSingh13的答案之后,我想澄清两个重要问题,无论谁遇到类似的问题:

1)Glenn Jackman解决方案无法正常工作,因为我需要将文本文件从DOS转换为Unix。我用dos2unix做了,但由于某种原因没有用(可能忘了将输出覆盖到旧文件?)。后来我用sed -i 's/\r$//' test.txt做了这件事。解决了这个问题,Glenn的解决方案现在可以解决了。对于我来说,拥有dos格式的文本文件已成为许多麻烦的源头。

2)我可能没有明确表示我只想在输入文件中定位特定的行;我的示例只有目标字符串,但实际文件包含我不想编辑的字符串。这可能是RavinderSingh13的剧本发生的误解,该剧本确实有效,但针对每一行。 希望这可以帮助未来的读者。谢谢你,Stackers,你再次救了一天:)

2 个答案:

答案 0 :(得分:3)

您拥有的内容(sed -r "s/${instring}/${instring}Z/g" $1)在左侧使用变量作为模式,在右侧使用纯文本

您想要做的是:

sed -r "s/${instring}/&Z/g" $1
# ....................^

其中&标记被替换为模式匹配的任何文本。在The s Command的文档中:

  

[T]他替换可以包含未转义的&字符,这些字符引用模式空间的整个匹配部分。

答案 1 :(得分:2)

编辑:如果您需要将正则表达式传递给脚本,那么以下可能会有所帮助,我之前的解决方案只是将一个字符附加到该行的最后一行。

cat script.ksh
value="$2"
sed  "s/$value/&Z/"  "$1"

运行脚本后:

./script.ksh X.*
XabcZ
XdefZ

在看到OP的评论以匹配从以下样式开始的小写字母或大写字母运行脚本的所有内容之后。

./script.ksh [A-Za-z]+*

请您试着跟随并告诉我这是否对您有帮助。

cat script.ksh
value="$2"
sed "s/$/$value/" "$1"

运行脚本后,我也在终端上得到了输出。

./script.ksh Input_file Z
XabcZ
XdefZ

如果您想将输出保存到Input_file中,可以在上面的代码中使用sed -i选项。