我想使用 sed 更改文本文件中如下所示的行:encoding="ISO-8859-1" target="1.1" 其中 target 的值未知,但 bash 脚本中名为 NEWNUMBER 的变量中的数字 [dot]number 为数字。我需要识别该整行 (encoding="ISO-8859-1" target=) 例如 NEWNUMBER=2.9 我似乎无法正确理解,但我对 sed 还很陌生。
答案1
您可能会错过以下几件事:
-r
使用扩展正则表达式运行的参数,-i
参数在文件中进行替换 - 你可能希望在确保表达式正确工作时使用它 - 否则你可能会损坏文件,[^\"]
方便地匹配除特定字符之外的所有内容。请注意,我已经转义了双引号,因为您的示例将使用来自 bash 脚本的一些变量,并且 sed 内容应该用双引号括起来才能正确注入变量。
只要你有正确的想法,休息就是你正确的做法:
- 在某些单个字符或类别之后使用
+
(至少出现一次)或*
(零次或多次出现)(例如:\w
匹配字母、数字或下划线),或者在多个字符/类别匹配之后使用(例如:[\w-]
匹配字母、数字、下划线或连字符)- 因此
[\w-]+
您将匹配类似这样的字符串ISO-8859-1
。
- 因此
- 添加组的使用,用 包围任何适当匹配的内容
( )
,并在 sed replace-all() 的右侧使用该匹配,sed 's/pattern/replacement/g'
通过将后续组匹配引用为\1
,/2
依此类推......- 例如随意回答007特工著名的问候语
echo "I'm Bond, James Bond." | sed -r "s/I'm (\w+), (\w+) \w+./Hello, \2 \1/g"
:)。
- 例如随意回答007特工著名的问候语
- 您可能希望以
^
标记行首的 来开始匹配,并以$
标记行尾的 来结束匹配(实际上确保您的匹配只匹配整行,而不是部分行)。
请分享您的尝试,这样我就能直奔主题。如果您做对了,也请分享您的经验,这样其他人就有可能避免同样的麻烦。
作为对评论的回应,我添加了使用 perl 和 lookbehind 的替代解决方案:
perl -pi.bak -e 's/(?<=encoding="ISO-8859-1" target=")(\d+\.\d+)/'$NEWNUMBER'/g' test
-i.bak
意味着你将直接对输入文件进行更改,并保存带有.bak
扩展名的备份副本-p
添加一个打印循环,允许处理输入文件的每一行 - 如果没有这个,即使是一行命令也不会成功-e
允许您将其作为单行脚本运行,而不是提供脚本文件(?<=pattern)
是一种后视 - 它使pattern
匹配项位于匹配项之前,但它不会成为匹配项的一部分(使其成为正则表达式中使用组的替代方案)- 您也可以使用它
grep
(使用-P
perl 正则表达式的参数),但显然不能sed
- 您也可以使用它