【问题标题】:delete lines between two patterns without deleting the pattern删除两个图案之间的线条而不删除图案
【发布时间】:2014-11-19 17:06:41
【问题描述】:

我有一个像下面这样的文件

[NAMES]
biren
bikash
dibya

[MAIL]
biren_k
bikash123
dibya008

我的输出应该如下所示

[NAMES]

[MAIL]

我尝试了下面的代码只是为了删除NAMESMAIL 之间的行,但它不起作用。

sed -n '/NAMES/{p; :a; N; /MAIL/ba; s/.*\n//}; p' input.txt

谁能帮忙...如果有的话我更喜欢perl代码...

注意:像 [NAMES][MAIL] ,我的实际文件中有很多标题。在这里,我刚刚展示了两个标题。我必须用新内容替换标题下方的内容(不是全部,仅选择随机行号的标题)。但首先我需要删除它们下面的内容。这就是为什么我需要这样的输出。有什么建议请...

【问题讨论】:

  • 你能简单解释一下为什么不能用基线文件(即[NAMES] [MAIL])覆盖文件吗?祝你好运。
  • perl -00 -nalwe'print $F[0]'
  • [NAMES][mail],我的文件中有很多标题。我想用新行替换每个标题下方的所有行。首先我需要删除每个标题下面的行。这就是我需要的@shellter
  • 那么@mpapec 的答案看起来可以回答您的问题。祝你好运。

标签: bash perl shell


【解决方案1】:

你可以修改sed

$ sed '/\[NAMES\]/, /\[MAIL\]/ {/^\[/p; d}' input
[NAMES]
[MAIL]
biren_k
bikash123
dibya008

【讨论】:

  • 非常感谢...你能帮我把行放在[NAMES]下面吗...我需要输出为`[NAMES]
    kumar
    avi

    [邮件]
    biren_k
    bikash123
    dibya008
  • 嗨,我在 perl 代码中使用了像 system("sed -i 's/\[NAMES\]/\[NAMES\]\nbiren\n/g' input.txt"); 这样的代码......它不起作用......你能帮帮我吗
  • @biren.K 不确定为什么要在 perl 中运行该程序。为什么不从 bash 运行 sed?还要包括[NAME][MAIL] 之间的行,这些值是随机给出的还是取自其他文件?
  • 这些值取自其他文件。我被要求使用 perl 脚本来完成。这就是我问的原因..
  • @biren.K 在这种情况下,您根本不需要使用sed。 perl 可以自己处理所有事情。试试看。祝你好运
【解决方案2】:

请尝试这可能对您的问题有所帮助:

%hashes = (
"[NAMES]" => "<br/>kumar<br/>avi<br/><br/>\n",
"[MAIL]" => "<br/>biren_k<br/>bikash123<br/>dibya008<br/>\n"
);

my @arr = <DATA>;
foreach my $snarr(@arr)
{
    chomp($snarr);
    push(@newarr, "$snarr\n$hashes{$snarr}"), if( $hashes{$snarr} );
}

print @newarr;


__DATA__
[NAMES]
biren
bikash
dibya

[MAIL]
biren_k
bikash123
dibya008

【讨论】:

    【解决方案3】:

    只需将 my @erase = qw[]; 之间的行替换为您要清空的 HEADERS。

    #!/usr/bin/env perl
    use strict;
    use warnings;
    
    push @ARGV, 'file.txt';
    # here list out the HEADERS
    # which content you wanna erase
    my @erase = qw[
        NAMES
        MAIL
    ];
    
    my %dump;
    my $header;
    # build a hash from your file
    while (<>) {
      if (/^\[([^\]]+)\]$/) {
        $header = $1;
        $dump{$header} = "";
        next;
      }
      $dump{$header} .= $_ if $header;
    }
    
    # replace the content
    # with empty string
    foreach (@erase) {
      $dump{$_} = "";
    }
    
    # now print it back to <STDOUT>
    foreach (sort keys %dump) {
      print "[$_]\n$dump{$_}\n";
    }
    

    【讨论】:

      【解决方案4】:

      我在这里找到了解决问题的方法:

      my @name_var = ();
      while (<STDIN>)
      {
        last if ($_ =~ /^\n/ );
        push(@name_var, $_);
      }
      
      my @mail_add = ();
      while (<STDIN>)
      {
        last if ($_ =~ /^\n/ );
        push(@mail_add, $_);
      }
      
      open(my $var, "input.txt") || die("Input File not found");
      open(my $out, ">temp.txt") || die("Temp File not created");
      while($line = <$var>)
      {
         # print $line;
          if( $line =~ /\[NAMES\]/)
          {
            print $out $line;
            print $out $name_var;
      
           while(($line = <$var>) && ($line !~ /^\n/))
            {
            }
          }
      
          if( $line =~ /\[MAIL\]/)
          {
            print $out $line;
            print $out $mail_add;
      
           while(($line = <$var>) && ($line !~ /^\n/))
            {
            }
          }       
          print $tcf_out $line;
      }
      
      close($var);
      close($out);
      open($var1,">input.txt") || die("failed to open\n");
      open($out1,"<temp.txt") || die("failed to open\n");
      while($fl = <$out1>)
      { 
        print $var1 $fl;
      }
      close($var1);
      close($out1);
      

      谢谢大家。我从堆栈溢出、perlmonk 和其他一些与 perl 相关的网站中得到了解决方案。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-28
        • 2018-12-26
        • 2014-01-06
        • 2010-11-28
        • 2018-07-12
        • 1970-01-01
        • 1970-01-01
        • 2018-01-16
        相关资源
        最近更新 更多