当找到文本时从文件中删除多行

当找到文本时从文件中删除多行

sed我已经看到了多个使用或删除单行的答案grep,但我需要搜索一行,删除该行,然后删除接下来的两行。例如,在文件中~/.profile我有如下几行:

#Set environment variable
export NAME=value
# (blank line here)

因此,我想搜索#Set environment variable并删除它,然后删除下一行export NAME=variable(内容无关紧要)和下面的空白行。export变量名称是动态的,但注释始终相同。可能还有其他export没有上述注释的变量,我不想删除它们。

我怎样才能做到这一点?

答案1

使用较新版本的 GNU sed(Ubuntu 自带),您可以逐字匹配换行符:

sed -z 's/#Set environment variable\nexport [^\n]\+\n\n//g' file.txt
  • -z选项将把输入文件的行视为以 ASCII NUL 而不是换行符结尾,因此我们可以使用来\n匹配新行

  • #Set environment variable\n将匹配第一行(带换行符)

  • export [^\n]\+\n将匹配以export

  • 由于第三行是空白的,只需这样\n做即可

  • 然后我们用空白替换整个匹配的模式以保留所需的部分

如果你想用修改后的内容覆盖文件:

sed -zi.bak 's/#Set environment variable\nexport [^\n]\+\n\n//g' file.txt

原始文件将保留为file.txt.bak,如果您不想这样,只需使用sed -zi

这是一个测试:

$ cat file.txt 
#Set environment variable
export NAME=value
#some text

#Set environment variable
export NAME=value

check
value

export some=value

#Set environment variable
export NAME=value

foo bar



$ sed -z 's/#Set environment variable\nexport [^\n]\+\n\n//g' file.txt 
#Set environment variable
export NAME=value
#some text

check
value

export some=value

foo bar

答案2

使用标准 sed 的删除命令可以很容易地完成此操作:

cp ~/.profile ~/.profile.bak
sed '/#Set environment variable/,+2 d' <~/.profile.bak >~/.profile

小心你的~/.profile

答案3

虽然你的问题看起来像是你正在寻找一种命令行方式来执行此操作,但如果我处于你的情况并且只想对一两个文件执行此操作,我会使用emacs

emacs能够学习一系列按键,然后根据需要重复这些按键。因此,对于你的情况,我会打开它~/.profileemacs然后输入

C-x ( C-s #Set environment variable C-a C-k C-k C-k C-x )

[用文字表达就是:Cx ( 表示“开始学习这个”;Cs 表示“搜索”,因此我们搜索 #Set 环境变量,然后 Ca 表示“回到行首,三个 Ck 表示“删除此行”,最后 Cx ) 表示“停止学习这个”。]

这些命令输入一次后,emacs 会删除三行,但它也学会了如何做,所以你现在可以输入

C-x e

它会再次这样做,或者

C-u 100 C-x e

它会执行 100 次(或当它找不到更多包含“#Set environment variable”的行时停止)。

使用 emacs 的优点是你可以“实时”看到你的编辑,对于像我这样担心一个 sed 拼写错误会删除很多我不想删除的东西的偏执狂来说,这让我更高兴 [当 emacs 中出现问题时你可以直接返回并用 进行修复C-_]。

相关内容