删除 file1 中与模式匹配的行并将这些删除的行保存到 file2

删除 file1 中与模式匹配的行并将这些删除的行保存到 file2

我有file1,并且我需要删除与模式匹配的行。但我想将这些删除的行保存在另一个file2.

sed    '/zz/!d' file1 > file2
sed -i '/zz/d' file1

有没有办法将这些命令合并为一个?

或者有更优雅的方法吗?

答案1

在 GNU Sed 上检查:

sed -ni '/zz/!{p;b};w file2' file1

标志必须按该顺序排列-ni

说明:我们不使用命令停止脚本d,而是设置标志(静默)并使用命令(打印当前模式空间)-n写入与模板不匹配的行,然后跳转到脚本末尾。与模式匹配的行到达命令,该命令将模式空间写入文件。pbw

答案2

perl -pi -e 'select( /zz/ ? STDOUT : ARGVOUT )' file1 > file2

-i处理 file1 的就地编辑。-p运行 perl 程序后打印行。程序需要做的就是选择输出的位置。在这种情况下,可以使用?:选择标准输出或ARGVOUT(这就是-i使用的)来实现。

答案3

对于任何 Awk:

awk '/zz/{print >> "file2"; next} 1' file1 > tmp && mv tmp file1

如果您不喜欢显式创建临时文件,请使用GNU awk:

gawk -i inplace '/zz/{print >> "file2"; next} 1' file1

如果您想截断而不是追加,请更改>>为。>file2

也可以看看:为什么 awk 中的“1”打印当前行?

答案4

perl只需与该标志一起使用-i,并将匹配的行打印到标准输出,以便您可以将它们重定向到文件:

$ cat file1
asdasd
baba zzbabab
asdasd
sadkzzpasdad

$ perl -i -ne 'if(/zz/){ print STDOUT } else{ print }' file1 > file2

You could rewrite the above via a string form of eval where we construct
 the above piece of perl code based on presence of zz:

$ perl -i -ne 'eval "print ".qw[STDOUT][!/zz/]' file1 > file2

$ cat file1
asdasd
asdasd

$ cat file2 
baba zzbabab
sadkzzpasdad

Perl 中的另一种方法可以是:

$ perl -pi -e 'print(STDOUT),s/.*//s if /zz/' file1 > file2
  • 使用自动打印模式-p
  • 将 zz 行打印到标准输出中,然后当它们通过模式写回到文件 1 时将它们清空-i

相关内容