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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/22086662/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 09:44:40  来源:igfitidea点击:

How to remove all lines in a file containing a variable, only when located on a line somewhere between braces in BASH?

bashsed

提问by Village

I am trying to remove all of the matches of $wordfrom a file, but only on lines where $wordis placed somewhere within {and }which also appear on the same line, e.g.:

我试图$word从文件中删除所有匹配项,但仅在$word放置在某处{并且}也出现在同一行上的行上,例如:

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

If $wordis set to "cat", then lines 1 and 3 are deleted, because "cat" appears between the {and }. If $wordis set to "like", then lines 1 and 2 are deleted, because this search term appears on those lines between the {and }. Line 3 is not deleted, because likeappears outside of the braces.

如果$word设置为“cat”,则删除第 1 行和第 3 行,因为“cat”出现在{和之间}。如果$word设置为“like”,则删除第 1 行和第 2 行,因为此搜索词出现在{和之间的那些行上}。第 3 行没有被删除,因为它like出现在大括号之外。

  • The braces are never nested.
  • The braces never appear split across lines.
  • 大括号从不嵌套。
  • 大括号永远不会出现跨行拆分。

I have tried various things, but these all returned errors:

我尝试了各种方法,但这些都返回了错误:

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

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

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

How can I remove all of the lines in a file containing a variable, but only when the found variable was on a line and found between two braces?

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

回答by cybeliak

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

\{in sed actually have a special meaning, not the literal {, you should just write a {to represent the literal character. (which would be confusing if you are well familiar with perl regex ...)

\{在 sed 中实际上有一个特殊的含义,而不是字面量{,你应该只写 a{来代表字面量字符。(如果您非常熟悉 perl regex,这会令人困惑...)

Edit:

编辑:

Be careful with -i, if this is in a script, and accidently $wordis not defined or set to empty string, this command will delete alllines containing { no matter what between }.

请注意-i,如果这是在脚本中,并且不小心$word未定义或设置为空字符串,则此命令将删除所有包含{ no matter what between }.

回答by Floris

I would take the answer that @cybeliak gave a little further. If you really want to match catand not, say scat, then you need to delimit your expression with word boundaries:

我会更进一步地接受@cybeliak 给出的答案。如果你真的想匹配cat而不是,比如说scat,那么你需要用单词边界来分隔你的表达式:

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

Note - I prefer to use ' 'style quotes to prevent any unintended side-effects...

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

As an aside, I am a big fan of notusing the -iflag. Pipe the result into a different file and confirm for yourself that it's good, before deleting the original.

顺便说一句,我是使用-i国旗的忠实粉丝。在删除原始文件之前,将结果通过管道传输到另一个文件中并自己确认它是好的。

回答by anubhava

Much easier to do with awk:

使用 awk 更容易:

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

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

回答by potong

This might work for you (GNU sed):

这可能对你有用(GNU sed):

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

N.B. $wordshould not contain }or /.

NB$word不应包含}/