具有指定字符串的两行之间的grep

时间:2015-11-03 16:17:13

标签: shell unix grep

我有这个简单的平台文件(file.txt)

a43
test1
abc
cvb
bnm
test2
test1
def
ijk
xyz
test2
kfo

我需要两种形式的test1和test2之间的所有行,firte one创建两个新文件,如

newfile1.txt:

test1
abc
cvb
bnm
test2

newfile2.txt

test1
def
ijk
xyz
test2

,第二个表单只创建一个新文件,如:

newfile.txt

test1abccvbbnmtest2
test1defijkxyztest2

你有任何建议吗?

修改

对于第二种形式。我用过这个

sed -n' / test1 /,/ test2 / p' file.txt> newfile.txt

但它给我一个像

的结果
test1abccvbbnmtest2test1defijkxyztest2

我需要一条返回行,如:

test1abccvbbnmtest2
test1defijkxyztest2

3 个答案:

答案 0 :(得分:0)

你可以使用这个awk:

awk -v fn="newfile.txt" '/test1/ {
   f="newfile" ++n ".txt";
   s=1
} s {
    print > f;
    printf "%s", $0 > fn
} /test2/ {
    close(f);
    print "" > fn;
    s=0
} END {
   close(fn)
}' file

答案 1 :(得分:0)

与sed和其他语言一样,Perl能够从文件中选择行范围,因此它非常适合您尝试的操作。

这个解决方案最终比我想象的要复杂得多。我没有理由在@ anubhava的awk解决方案上使用它。但我写了它,所以这里是:

#!/usr/bin/perl

use 5.010;
use strict;
use warnings;

use constant {
  RANGE_START => qr/\Atest1\z/,
  RANGE_END => qr/\Atest2\z/,
  SUMMARY_FILE => 'newfile.txt',
  GROUP_FILE => 'newfile%d.txt'
};

my $n = 1; # starting number of group file
my @wg; # storage for "working group" of lines

# Open summary file to write to.
open(my $sfh, '>', SUMMARY_FILE) or die $!;

while (my $line = <>) {
  chomp $line;

  # If the line is within the range, add it to our working group.
  push @wg, $line if $line =~ RANGE_START .. $line =~ RANGE_END;

  if ($line =~ RANGE_END) {
    # We are at the end of a group, so summarize it and write it out.

    unless (@wg > 2) {
      # Discard any partial or empty groups.
      @wg = ();
      next;
    }

    # Write a line to the summary file.
    $sfh->say(join '', @wg);

    # Write out all lines to the group file.
    my $group_file = sprintf(GROUP_FILE, $n);
    open(my $gfh, '>', $group_file) or die $!;
    $gfh->say(join "\n", @wg);
    close($gfh);

    printf STDERR "WROTE %s with %d lines\n", $group_file, scalar @wg;

    # Get ready for the next group.
    $n++;
    @wg = ();
  }
}

close($sfh);

printf STDERR "WROTE %s with %d groups\n", SUMMARY_FILE, $n - 1;

要使用它,请将上述行写入名为eg的文件中。 ranges.pl,并使其chmod +x ranges.pl可执行。然后:

$ ./ranges.pl plat.txt 
WROTE newfile1.txt with 5 lines
WROTE newfile2.txt with 5 lines
WROTE newfile.txt with 2 groups
$ cat newfile1.txt 
test1
abc
cvb
bnm
test2
$ cat newfile.txt
test1abccvbbnmtest2
test1defijkxyztest2

答案 2 :(得分:0)

对于第二个,您可以在“test2”添加\n

之后添加新行
sed -n '/test1/,/test2/p' file.txt  | sed  -e 's/test2/test2\n/g' > newfile.txt 

sed对于创建多个文件没有用,所以对于第一个文件,你应该找到另一个解决方案。