如何找到与模式匹配的行并将其删除?


14

在包含许多行的文件中,我要删除以开头的行HERE IT IS

如何仅使用命令行工具执行此操作?


2
虽然有点不合常规,但您可以这样使用vimvim '+g/^HERE IT IS/d' +wq test.txt;)
Doorknob 2015年

@Doorknob,谢谢您指出这一点。实际上,我正在使用vim
micgeronimo 2015年

Answers:


28

尝试sed

sed -i '/^HERE IT IS/d' <file>

警告:使用以下-i开关时最好备份sed

sed -i.bak '/^HERE IT IS/d' <file>

原始文件将保留为<file>.bak,修改后的文件将为<file>


如何在匹配的字符串后放置换行符并写入换行符?
micgeronimo 2015年

2
sed -i 's/^HERE IT IS/HERE IT IS\n/' <file>
heemayl

1
@micgeronimo:非常乐意提供帮助。请检查我的编辑。
heemayl

6
@micgeronimo尝试在原始问题中提出您真正想要回答的问题(请记住您可以对其进行编辑),而不是通过可能会被清除/删除的评论来提出。您可以使用sed '/^HERE IT IS/G' file
steeldriver

1
sed用法是如此专业。
LakshyaAg 2015年

18

除了很好的grepsed聪明的你已经收到了,这里有一些其他的工具可以做同样的事情:

  • 一些Perl方式:

    perl -ne '/^HERE IT IS/ || print' file > newfile
    perl -ne 'print if !/^HERE IT IS/' file > newfile
    perl -ne 'print unless /^HERE IT IS/' file > newfile
    

    您可以将-i开关添加到任何示例中,以在适当位置编辑文件:

    perl -i.bak -ne '/^HERE IT IS/ || print' file        
    
  • (g)awk

    awk '!/^HERE IT IS/' file > newfile
    

    GNU的较新版本(4.1.1和更高版本)awkawkLinux上的默认设置)也可以就地编辑文件:

    gawk -i inplace  '!/^HERE IT IS/' file
    
  • 壳牌(bashzshksh,可能其他人)。虽然这很愚蠢,但是可以做到,但是其他工具更好。

    while IFS= read -r line; do 
      [[ $line =~ ^"HERE IT IS" ]] || printf "%s\n" "$line"
    done < file > newfile
    

1
你只是在炫耀!;-)(但是您获得了赞誉,因为它很聪明,我学到了很多东西,bash使我大声笑)
Fabby 2015年

bash应该使用printf "%s\n" "$line":引用$ line保留空白,并避免一些回声问题(解释特殊字符等)。并且避免了也添加--
Olivier Dulac

@OlivierDulac足够公平。我不想使边缘情况复杂化,但是由于Cuanglm已添加IFS=-r,所以我可能会一直进行并使其健壮。
terdon

@terdon:这一切都是为了更好的发展^^(尽管我已经+1了,因为它对初学者
很有帮助

2
@OlivierDulac我可以向您保证,如果我在Unix和Linux上发布,我会使用printf,IFS =,-r和引号:)。我经常为那些不太熟悉命令行的非盟用户简化事情。
terdon

13

我会用grep它们过滤掉。例如 :

grep -v "^HERE IT IS" infile > outfile

然后将outfile移回infile。


聪明的思考
Anwar

5

sed 绝对是要走的路。

对命令@heemayl的这种稍加修改将使您删除该行,无论模式中是否使用相同的大小写,这都是由于模式引用中的I所致。

sed -i '/HERE IT IS/Id' <file>

如果您要在目录中包含多个文件,可以将其与find结合使用。

find . -maxdepth 1 -type f -exec sed -i.bak '/HERE IT IS/Id' {} +

maxdepth选项意味着这不会递归到目录中。


4

另一个python选项:

#!/usr/bin/env python3
[print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]

其中f是引号之间文件的路径。


4

格列普

grep -P '^(?!HERE IT IS)' file

(?!HERE IT IS)否定超前断言,使正则表达式引擎匹配所有行的起始边界(通常由^仅在其后没有字符串时才)HERE IT IS

蟒蛇

#!/usr/bin/python3
import sys
fil = sys.argv[1]
with open(fil) as f:
    for line in f:
        if not line.startswith('HERE IT IS'):
            print(line, end="")

将脚本保存在一个文件中,script.py然后说,然后在终端上通过以下命令运行它。

python3 script.py infile

您可以在其中使用regex,例如[print(l, end = "") for l in open(fil).readlines() if not re.match("HERE IT IS", l)],但效率不比得多startswith。我想知道如何[print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]不会在列表中产生输出。
Avinash Raj 2015年

我第一次遇到它,对我来说看起来很奇怪。它为已定义列表中的所有项目生成打印命令(或您要执行的任何操作)。
2015年

删除它,只是为了好玩:)
Jacob Vlijm

1

您可以在Ex模式下使用Vim:

ex -sc 'g/^HERE IT IS/d' -cx file
  1. g 全球搜寻

  2. d 删除

  3. x 保存并关闭

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.