如何从文件中提取文本行?

时间:2008-11-17 18:08:35

标签: regex perl sed awk grep

我有一个充满文件的目录,我需要从它们中拉出页眉和页脚。它们都是可变长度的,因此使用头部或尾部不起作用。每个文件都有我可以搜索的行,但我不想在结果中包含该行。

通常是

*** Start (more text here)

结尾
*** Finish (more text here)

我希望文件名保持不变,所以我需要覆盖原件,或者写入不同的目录,我会自己覆盖它们。

哦,是的,它当然在Linux服务器上,所以我有Perl,sed,awk,grep等。

7 个答案:

答案 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中执行此操作的惯用方法,尽管您不必修改文件就可以使用它。