代码之家  ›  专栏  ›  技术社区  ›  bbutle01

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

  •  2
  • bbutle01  · 技术社区  · 16 年前

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

    通常是

    *** Start (more text here)
    

    *** Finish (more text here)
    

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

    7 回复  |  直到 16 年前
        1
  •  3
  •   AndyG    8 年前

    试试 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”。

        2
  •  2
  •   Svante    16 年前

    csplit inputfile %^\*\*\* Start%1 /^\*\*\* Finish/ %% {*}
    

    这将生成所需的文件 xx00 . 您可以通过选项更改此行为 --prefix , --suffix --digits ,但请看 manual csplit 设计用于生成多个文件,不可能生成没有后缀的文件,因此您必须手动或通过脚本进行覆盖:

    csplit $1 %^\*\*\* Start%1 /^\*\*\* Finish/ %% {*}
    mv -f xx00 $1
    

    根据需要添加循环。

        3
  •  1
  •   Drakosha    16 年前

    得到 标题

    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 .

        4
  •  0
  •   Jonathan Lonowski    16 年前

    $ sed -i '/^\*\*\* Start/,/^\*\*\* Finish/d!' *
    

    或者…不太确定…但是,如果它起作用,也应该删除起点和终点线:

    $ sed -i -e '/./,/^\*\*\* Start/d' -e '/^\*\*\* Finish/,/./d' *
    

    d! sed 你不确定。
    而且,我写这篇文章完全是基于(可能是糟糕的)记忆。

        5
  •  0
  •   brian d foy    16 年前

    一个快速的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;  
    
        6
  •  0
  •   brian d foy    16 年前

    中的一些示例 perlfaq5: How do I change, delete, or insert a line in a file, or append to the beginning of a file? 也许会有帮助。你必须使它们适应你的情况。此外,Leon的触发器操作符答案是在Perl中实现这一点的惯用方法,尽管您不必修改文件来使用它。

        7
  •  0
  •   brian d foy    16 年前

    覆盖原始文件的Perl解决方案。

    #!/usr/bin/perl -ni
    if(my $num = /^\*\*\* Start/ .. /^\*\*\* Finish/) {
        print if $num != 1 and $num + 0 eq $num;
    }