sed 删除具有精确模式的行

sed 删除具有精确模式的行

我试图找到文件$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

相关内容