perl从文件中删除字符串块并保存到文件 [英] perl remove string block from file and save to file

查看:76
本文介绍了perl从文件中删除字符串块并保存到文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个看起来像这样的文件:

 字符串1 {abc {会话1}合理的价格 {编号LU0432618274456来源4服务xyz}}字符串2 {abc {会话23}合理的价格 {ID LU036524565456171来源4慈济}} 

我的程序应读取具有给定搜索参数(例如字符串1")的文件,并搜索整个块,直到}"为止,然后从文件中删除该部分.有人可以帮忙...到目前为止,我有一些代码,但是我该如何删除并再次保存到同一文件?

  my $ fh = IO :: File-> new("$ fname","r")或死亡(错误:未找到策略文件\" $ fname \.");while($ line =< $ fh>){如果($ line =〜/^ \ s * string 1 \ s * \ w + \ s * \ {\ s * $/){$ inside_json_msg = 1;$ msg_json.= $ line;}别的 {如果($ inside_json_msg){如果($ line =〜m/^ \} \ s * $/){$ msg_json.= $ line如果已定义($ line);$ inside_json_msg = 0;} 别的 {$ msg_json.= $ line;}}}} 

解决方案

您的代码提到了JSON,但您的数据不是JSON.如果它是JSON,而您转录得很糟糕,请使用一个JSON库.

但是,如果您的数据不是JSON,则可以执行以下操作.

 #!/usr/bin/perl使用严格使用警告;my $ match = shift或die我需要一个字符串来匹配\ n";while(< DATA>){#如果这是一个块的开始,我们要删除...如果(/^ \ s * $ match \ s + {/){#将$ braces设置为1(如果该行在此行关闭,则设置为0)我的$大括号=/}/吗?0:1;#虽然$大括号为非零while($大括号){#读取文件的下一行$ _ =< DATA> ;;#适当地增加或减少$大括号$大括号-如果/}/;$大括号++,如果/{/;}} 别的 {#否则,只打印行打印;}}__数据__字符串1 {abc {会话1}合理的价格 {编号LU0432618274456来源4服务xyz}}字符串2 {abc {会话23}合理的价格 {ID LU036524565456171来源4慈济}} 

当前,这只是将输出打印到控制台.我使用 DATA 文件句柄进行更轻松的测试.留给读者练习是使用真实的文件句柄:-)

更新:我认为我不喜欢使用正则表达式匹配 $ braces 的所有增量和减量.因此,这是另一个(改进的?)版本,它使用 y/.../.../来计算行中右括号和右括号的出现次数.此版本的可读性可能会稍差(语法突出显示工具肯定会这样认为).

 #!/usr/bin/perl使用严格使用警告;my $ match = shift或die我需要一个字符串来匹配\ n";while(< DATA>){如果(/^ \ s * $ match \ s + {/){我的$大括号= y/{//-y/}//;while($大括号){$ _ =< DATA> ;;$大括号-= y/}//;$大括号+ = y/{//;}} 别的 {打印;}}__数据__字符串1 {abc {会话1}合理的价格 {编号LU0432618274456来源4服务xyz}}字符串2 {abc {会话23}合理的价格 {ID LU036524565456171来源4慈济}} 

更新2:好吧,我最初说的是,处理真正的文件句柄将留给读者练习.但这是一个执行此操作的版本.

 #!/usr/bin/perl使用严格使用警告;my $ match = shift或die我需要一个字符串来匹配\ n";打开我的$ fh,'+<','data'或死亡$ !;#读取文件中的所有数据我的@data =< $ fh> ;;#清空文件寻求$ fh,0,0;截断$ fh,0;我的$ x = 0;而($ x< = $#data){$ _ = $ data [$ x ++];如果(/^ \ s * $ match \ s + {/){我的$大括号= y/{//-y/}//;while($大括号){$ _ = $ data [$ x ++];$大括号-= y/}//;$大括号+ = y/{//;}} 别的 {打印$ fh $ _;}} 

当前,我已经将文件名硬编码为 data .我希望很明显如何解决该问题.

I have a file that looks like this:

string 1 {
    abc { session 1 }
    fairPrice {
            ID LU0432618274456
            Source 4
            service xyz
    }
}
string 2 {
    abc { session 23 }
    fairPrice {
            ID LU036524565456171
            Source 4
            service tzu 
    }
}

My program should read in the file with a search-parameter given (for example "string 1") and search the complete block until "}" and remove that part from the file. Can someone assist on that...I have some code so far but how can I do the removal and saving to the same file again?

my $fh = IO::File->new( "$fname", "r" ) or die ( "ERROR: Strategy file      \"$fname\" not found." );
while($line=<$fh>)
{
    if ($line =~ /^\s*string 1\s*\w+\s*\{\s*$/) {
            $inside_json_msg = 1;
            $msg_json .= $line;
    }
    else {
            if ($inside_json_msg)
            {
               if ($line =~ m/^\}\s*$/) {

                 $msg_json.= $line if defined($line);
                 $inside_json_msg = 0;
               } else {
                 $msg_json .= $line;
               }
            }
    }
}

解决方案

You code mentions JSON, but your data isn't JSON. If it is JSON and you've just transcribed it badly, then please use a JSON library.

But if your data isn't JSON, then something like this will do the trick.

#!/usr/bin/perl

use strict;
use warnings;

my $match = shift or die "I need a string to match\n";

while (<DATA>) {
  # If this is the start of a block we want to remove...
  if (/^\s*$match\s+{/) {
    # Set $braces to 1 (or 0 if the block closes on this line)
    my $braces = /}/ ? 0 : 1;
    # While $braces is non-zero
    while ($braces) {
      # Read the next line of the file
      $_ = <DATA>;
      # Increment or decrement $braces as appropriate
      $braces-- if /}/;
      $braces++ if /{/;
    }
  } else {
    # Otherwise, just print the line
    print;
  }
}

__DATA__
string 1 {
    abc { session 1 }
    fairPrice {
            ID LU0432618274456
            Source 4
            service xyz
    }
}
string 2 {
    abc { session 23 }
    fairPrice {
            ID LU036524565456171
            Source 4
            service tzu 
    }
}

Currently, this just prints the output to the console. And I use the DATA filehandle for easier testing. Switching to use real filehandles is left as an exercise for the reader :-)

Update: I decided that I didn't like all the incrementing and decrementing of $braces using regex matches. So here's another (improved?) version that uses y/.../.../ to count the occurrences of opening and closing braces in the line. It's possible that this version might be slightly less readable (the syntax highlighter certainly thinks so).

#!/usr/bin/perl

use strict;
use warnings;

my $match = shift or die "I need a string to match\n";

while (<DATA>) {
  if (/^\s*$match\s+{/) {
    my $braces = y/{// - y/}//;
    while ($braces) {
      $_ = <DATA>;
      $braces -= y/}//;
      $braces += y/{//;
    }
  } else {
    print;
  }
}

__DATA__
string 1 {
    abc { session 1 }
    fairPrice {
            ID LU0432618274456
            Source 4
            service xyz
    }
}
string 2 {
    abc { session 23 }
    fairPrice {
            ID LU036524565456171
            Source 4
            service tzu 
    }
}

Update 2: Ok, I originally said that dealing with real filehandles would be left as an exercise for the reader. But here's a version that does that.

#!/usr/bin/perl

use strict;
use warnings;

my $match = shift or die "I need a string to match\n";

open my $fh, '+<', 'data' or die $!;

# Read all the data from the file
my @data = <$fh>;

# Empty the file
seek $fh, 0, 0;
truncate $fh, 0;

my $x = 0;
while ($x <= $#data) {
  $_ = $data[$x++];
  if (/^\s*$match\s+{/) {
    my $braces = y/{// - y/}//;
    while ($braces) {
      $_ = $data[$x++];
      $braces -= y/}//;
      $braces += y/{//;
    }
  } else {
    print $fh $_;
  }
}

Currently, I've hard-coded the filename to be data. I hope it's obvious how to fix that.

这篇关于perl从文件中删除字符串块并保存到文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆