我试图找到文件$i
中模式的精确匹配C1.txt
,并使用 sed 命令删除匹配行。但最终遇到了问题。请在下面找到我的发现和其他详细信息。
C1.txt
# file: /home/mytest/data # owner: own # group: group-sm user::r-x group::rwx mask::rwx other::--- default:user::rwx default:group::r-x default:group:smr:rwx default:group:agm:r-x default:mask::rwx default:other::---
# file: /home/mytest/datasr123 # owner: own # group: group-sm user::r-x group::rwx mask::rwx other::---
变量值
i=/home/mytest/data
代码
#!/bin/bash
Input=C1.txt
j=0
while IFS= read -r line;
do
j=$((j+1))
Exists=$(echo $line | grep -iwoP "$i" )
if [[ ! -z "$Exists" ]]; then
sed -i "$j /\b"$i"\b/d" "$Input"
fi
done <"$Input"
预期结果
C1.txt
# file: /home/mytest/datasr123 # owner: own # group: group-sm user::r-x group::rwx mask::rwx other::---
错误信息
sed: -e expression #1, char 3: unknown command: `/'
答案1
您收到错误的原因是您的搜索字符串包含/
与标记字符混淆的字符。换句话说,您要求sed
这样做:
sed "//home/mytest/datasr123/d"
这会产生您看到的错误。 IOW,该模式不能包含您用作标记的字符。如果你知道你的模式确实如此不是包含给定字符,您可以使用该字符作为标记;例如,由于您的搜索字符串中没有;
,您可以这样做:
sed "\;/home/mytest/datasr123;d"
或就以下而言$i
:
sed "\;$i;d"
有关如何指定地址的详细信息,请参阅sed
下面的手册页。Addresses
当然,这是否有用取决于您是否知道搜索字符串中永远不会出现的字符:任何字符都可以作为标记,但如果您的搜索字符串是由用户输入的,则不能保证您所输入的内容是正确的。 select 不会出现在搜索字符串中 - 您必须扫描它才能找到未出现在其中的字符。
最简单的方法是不是完全可以使用sed
,但可以依靠 grep (感谢@Kusalananda 修复了我的愚蠢错误):
grep -v -F -e "$i" -- <file>
将仅显示与模式不匹配的行(即-v
--F
告诉 grep 按字面意思解释字符串,而不是正则表达式,因此例如*
and按.
字面匹配;-e
允许模式以 a 开头-
并且不被解释作为一个选项grep
;并且--
允许文件名以 a 开头-
,并且不被解释为grep
;的选项最后两个是总是最好在脚本内进行调用,因为您永远不知道这种情况何时会出现,尽管我们在交互调用grep
时大多会逃脱它)。grep
但请注意:问题已被编辑,模式的更改已无效每一个这个答案中的方法完全。模式匹配两个都输入中的行,因此它们都将被删除。您将不得不以某种方式重新解释该模式,例如查找 not for"$i"
因为这将匹配两者;相反,寻找"${i} "
额外的空格将与第一行匹配但不与第二行匹配,或者"${i}s"
与第二行匹配但与第一行不匹配。另请注意,使用 时-F
,您不能使用字符类(因此\b
已被淘汰)。
答案2
原文grep -iwoP
似乎并没有反映出“完全匹配”的想法……但是
要删除与搜索字符串完全匹配的完整行,则需要在行的开头^
和结尾处进行锚定。$
sed "\|^$i$|d" C1.txt