我有一个充满文件的目录,我需要从它们中拉出页眉和页脚。它们都是可变长度的,因此使用头部或尾部不起作用。每个文件都有我可以搜索的行,但我不想在结果中包含该行。
通常是
*** Start (more text here)
以
结尾*** Finish (more text here)
我希望文件名保持不变,所以我需要覆盖原件,或者写入不同的目录,我会自己覆盖它们。
哦,是的,它当然在Linux服务器上,所以我有Perl,sed,awk,grep等。
答案 0 :(得分:3)
尝试flip flop!“..”运算符。
# flip-flop.pl
use strict;
use warnings;
my $start = qr/^\*\*\* Start/;
my $finish = qr/^\*\*\* Finish/;
while ( <> ) {
if ( /$start/ .. /$finish/ ) {
next if /$start/ or /$finish/;
print $_;
}
}
然后你可以使用-i perl开关来更新你的文件......
$ perl -i'copy_*' flip-flop.pl data.txt
...更改data.txt但预先复制为“copy_data.txt”。
答案 1 :(得分:2)
GNU coreutils是你的朋友......
csplit inputfile %^\*\*\* Start%1 /^\*\*\* Finish/ %% {*}
这会将您想要的文件生成为xx00
。您可以通过选项--prefix
,--suffix
和--digits
更改此行为,但请亲自查看manual。由于csplit
旨在生成许多文件,因此无法生成没有后缀的文件,因此您必须手动或通过脚本进行覆盖:
csplit $1 %^\*\*\* Start%1 /^\*\*\* Finish/ %% {*}
mv -f xx00 $1
根据需要添加循环。
答案 2 :(得分:1)
获取标题:
cat yourFileHere | awk '{if (d > 0) print $0} /.*Start.*/ {d = 1}'
获取页脚:
cat yourFileHere | awk '/.*Finish.*/ {d = 1} {if (d < 1) print $0}'
要根据需要将文件从页眉转换为页脚:
cat yourFileHere | awk '/.*Start.*/ {d = 1; next} /.*Finish.*/ {d = 0; next} {if (d > 0) print $0}'
还有一种方法,使用csplit命令,你应该尝试类似的东西:
csplit yourFileHere /Start/ /Finish/
检查名为'xxNN'的文件,其中NN正在运行编号,同时查看csplit manpage。
答案 3 :(得分:0)
也许?使用not-delete开始结束。
$ sed -i '/^\*\*\* Start/,/^\*\*\* Finish/d!' *
或...不太确定...但是,如果它有效,也应该删除Start和Finish行:
$ sed -i -e '/./,/^\*\*\* Start/d' -e '/^\*\*\* Finish/,/./d' *
d!
可能取决于您拥有的sed
的构建 - 不确定
而且,我完全写了(可能很差)内存。
答案 4 :(得分:0)
快速Perl黑客,没有经过测试。我在sed或awk上不够流利,不能用它们来获得这种效果,但我会对如何做到这一点感兴趣。
#!/usr/bin/perl -w
use strict;
use Tie::File;
my $Filename=shift;
tie my @File, 'Tie::File', $Filename or die "could not access $Filename.\n";
while (shift @File !~ /^\*\*\* Start/) {};
while (pop @File !~ /^\*\*\* Finish/) {};
untie @File;
答案 5 :(得分:0)
覆盖原始文件的Perl解决方案。
#!/usr/bin/perl -ni
if(my $num = /^\*\*\* Start/ .. /^\*\*\* Finish/) {
print if $num != 1 and $num + 0 eq $num;
}
答案 6 :(得分:0)
perlfaq5: How do I change, delete, or insert a line in a file, or append to the beginning of a file?中的一些示例可能有所帮助。你必须根据自己的情况调整它们。此外,Leon的触发器操作员答案是在Perl中执行此操作的惯用方法,尽管您不必修改文件就可以使用它。