我有包含如下行的文件。想要替换-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"/'