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
能够学习一系列按键,然后根据需要重复这些按键。因此,对于你的情况,我会打开它~/.profile
,emacs
然后输入
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-_
]。