我正在尝试使用 sed 来搜索其中包含 / 的确切字符串的出现。以下是我正在尝试的方法,但没有运气。
input_string="/path /path1 /path2"
search_string="/path"
input_string=echo $input_string | sed "s#\b$search_string\b##g"
但是当我运行这些命令序列时,我仍然使用 input_string 来包含值“/path /path1 /path2”而不是“/path1 /path2”
我什至尝试过input_string=echo $input_string | sed "s#\<$search_string\>##g"
但没有运气
我正在使用 RHEL6.5 并从 shell 运行此命令。
答案1
这里的问题是/
在 中的模式中$search_string
。
由于/
不是字母数字字符,因此不被视为“单词”。这意味着该模式\</path\>
将不匹配,/path
因为 之前没有字边界/
。
将搜索字符串更改为/path\>
(ie s##$search_string\>##g
),或者使用/path[^0-9]
, 或者,对于这些特定的输入数据和搜索字符串,您可以简单地用作s#$search_string ##g
替换。
答案2
简短的回答
使用这个命令来得到你想要的:
input_string=$(echo $input_string | sed "s#$search_string\b##g")
长答案
为什么sed
不更换
\b
表示单词边界,这是它的定义:
元字符 \b 是一个锚点,就像插入符号和美元符号一样。它在称为“单词边界”的位置进行匹配。该匹配的长度为零。
三种不同的位置都可以作为单词边界:
- 如果第一个字符是单词字符,则在字符串中的第一个字符之前。
- 在字符串中的最后一个字符之后,如果最后一个字符是单词字符。
- 字符串中的两个字符之间,其中一个是单词字符,另一个不是单词字符。
找到了这里。因此,您的第一个字符search_string
是 a ,并且由于第一条规则,/
似乎无法找到单词边界(因为不是单词字符)。sed
/
为什么结果不存储在input_string
您需要首先执行两个命令(echo
和sed
),然后将结果存储在变量 中input_string
。为此,请将这两个命令放入$()
.这将使它们执行并将结果返回到您的变量(请参阅简短的回答)。
我知道这不是完整的答案,但这就是我得到的全部。
答案3
精确的单词匹配sed
是很棘手的,特别是如果您想编写一个可移植的解决方案,或者您对“单词”的定义包含除_
(如您的情况)之外的特殊字符。我发现执行此操作的最佳方法是考虑单词可能出现在输入行中的所有 4 种情况:
- 一开始
- 在最后
- 在开头和结尾(占据整行)
- 在中间的某个地方
如果您对单词的定义只是一系列非空白字符,那么以下解决方案应该适合您(经过测试):
_s='[ ]' # contains a space and a literal tab character (CTRL-V + TAB) input_string=`echo "$input_string" | sed \ -e "s|^$search_string\\($_s\\)|\\1|g" \ -e "s|\\($_s\\)$search_string$|\\1|g" \ -e "s|^$search_string$||g" \ -e "s|\\($_s\\)$search_string\\($_s\\)|\\1\\2|g"`
请注意,我选择了|
作为分隔符而不是#
.这是因为#
可以显示在文件名中(例如,Emacs 自动保存文件) while|
是保留的,至少在 Linux 上是这样。另请注意,输出将包含每个 实例周围的空白字符$search_string
。如果您想省略空格,可以使用它(已测试):
_s='[ ]' # contains a space and a literal tab character (CTRL-V + TAB) input_string=`echo "$input_string" | sed \ -e "s|^$_s*$search_string$_s\\{1,\\}||g" \ -e "s|$_s\\{1,\\}$search_string$_s*$||g" \ -e "s|^$search_string$||g" \ -e "s|\\($_s\\)$search_string$_s\\{1,\\}|\\1|g"`
$search_string
最后一个表达式看起来有点不同,并且有充分的理由 -一旦处理输入行到了这一步,您就不想删除两侧的空格,因为这样做时,您将删除不匹配之间的空格两边的单词$search_string
,这会将它们粘在一起。
最后说明:
- 您也许可以省略表达式
g
中的一些修饰符sed
,但保留它们也没什么坏处。 - 这可能是不言而喻的,但如果您
$search_string
是一条路径,则它不能包含任何空格。