如何删除包含变量的文件中的所有行,只有当它位于BASH中的大括号之间的某一行时?

时间:2014-02-28 05:02:48

标签: bash sed

我正在尝试从文件中删除$word的所有匹配项,但仅限$word位于{}内的行{}}在同一行,例如:

{The cat liked} the fish.
The mouse {did not like} the cat.
The {cat did not} like the spider.

如果$word设置为“cat”,则会删除第1行和第3行,因为“{”会出现在{}之间。如果$word设置为“赞”,则会删除第1行和第2行,因为此搜索字词会显示在{}之间的这些行上。第3行不会被删除,因为like出现在大括号外。

  • 大括号永远不会嵌套。
  • 大括号永远不会出现在线条之间。

我尝试了各种各样的东西,但这些都返回了错误:

sed -i "/\{*$word*\}/d" ./file.txt

sed -i "/\{.*$word.*\}/d" ./file.txt

sed -i "/\{(.*)$word(.*)\}/d" ./file.txt

如何删除包含变量的文件中的所有行,但只有当找到的变量在一行上并且在两个大括号之间找到时才会删除?

4 个答案:

答案 0 :(得分:4)

sed -i "/{.*$word.*}/d" ./file.txt
sed中的

\{实际上有一个特殊含义,而不是文字{,你应该只写一个{来表示文字字符。 (如果你对perl正则表达式很熟悉,那会很混乱......)

修改

小心-i,如果这是在脚本中,并且意外地$word未定义或设置为空字符串,则此命令将删除包含{的所有所有行{1}}。

答案 1 :(得分:3)

我会接受@cybeliak给出的答案。如果你真的想要匹配cat而不是scat,那么你需要用词边界来界定你的表达式:

sed '/{.*[[:<:]]'$word'[[:>:]].*}/d'

注意 - 我更喜欢使用' '样式引号来防止任何意外的副作用......

顺便说一句,我是使用-i标志的 not 的忠实粉丝。在删除原始文件之前,将结果传送到另一个文件并确认自己是好的。

答案 2 :(得分:2)

使用awk更容易:

awk -v s="cat" -F '[{}]' '!($2 ~ s)' file
The mouse {did not like} the cat.

awk -v s="like" -F '[{}]' '!($2 ~ s)' file
The {cat did not} like the spider.

答案 3 :(得分:1)

这可能适合你(GNU sed):

sed -i '/{[^}]*'"$word"'[^}]*}/d' file 

N.B。 $word不应包含}/