sed 替换引号中的单词

sed 替换引号中的单词

我有包含如下行的文件。想要替换-s和后面引号中的单词-e。尝试过sed但没有成功。

文件内容

abc -s "today" -e "today" def
abc -s "yesterday" -e "yesterday" def
abc -s "3 days ago" -e "3 days ago" def

尝试过的命令

sed 's|-s "*" -e "*"|-s "1" -e "2"|g' <filename>

所需输出

abc -s "1" -e "2" def
abc -s "1" -e "2" def
abc -s "1" -e "2" def

答案1

您自己的尝试的主要问题是,这"*"意味着“匹配零个或多个双引号,后跟另一个双引号”。这是因为*是一个正则表达式修饰符,表示“前一个表达式的零个或多个”。这意味着"*"将匹配",等字符串"""""

除此之外,您不必为命令使用不同的分隔符,并且即使您不希望每行进行多次替换,也可以在末尾s///使用。/g但这些只是与风格有关的问题。


有多种方法可以使用 执行此操作sed,但所有方法都必须以某种方式匹配双引号之间的字符串。双引号之间的字符串可以通过正则表达式进行匹配"[^"]*",即“匹配一个双引号,然后零个或多个非双引号字符,后跟另一个双引号字符”。

$ sed -e 's/-s "[^"]*"/-s "1"/' -e 's/-e "[^"]*"/-e "2"/' file
abc -s "1" -e "2" def
abc -s "1" -e "2" def
abc -s "1" -e "2" def

上面使用了两个分离表达式匹配并替换给定选项后面的字符串,这也意味着

  • 输入中给出的选项顺序并不重要(-s "whatever"将始终被替换为-s "1"-e "whatever"将始终被替换-e "2"),
  • 它使得选项之间的空格数量无关紧要(例如更改-s "[^"]*"-s *"[^"]*"也允许选项和选项参数之间有多个空格),
  • 是否存在其他选项并不重要(也不重要这些选项相对于-s-e选项的排序方式),并且
  • -s如果仅存在和之一-e,而不存在另一个,则存在的选项和选项参数将被替换。

如果您还需要仅在以 开头的行上进行替换abc

sed -e '/^abc/{' -e 's/-s "[^"]*"/-s "1"/' -e 's/-e "[^"]*"/-e "2"/' -e '}' file

-e或者命令中没有所有这些选项sed

sed '/^abc/{ s/-s "[^"]*"/-s "1"/; s/-e "[^"]*"/-e "2"/; }' file

如果您还需要确保您修改的行以 结尾,请更改/^abc/为。/^abc.*def$/def

答案2

Sed 使用正则表达式,而不是通配符模式。*表示“重复前面的元素零次或多次”,并且您需要重复.这意味着“任何内容”:

sed 's/-s ".*" -e ".*"/-s "1" -e "2"/'

相关内容