使用 Perl,如何搜索字符串然后在其后添加不同的字符串行?
Using Perl, how to search a string then add a distinct line of string after it?
我在使用 Perl 时遇到了一些麻烦。对如何进行这个非常简单的搜索感到绝望,然后在匹配后添加一个新行。
例如,在我的文件中,我将搜索一个名为 "TSET" 的重复字符串,然后在该行之后我将不得不添加一个不同的标签,比如 "tset0:"(当然是在新行中)并且它需要为下一个匹配增加 "tset1:" 但它始终是相同的搜索字符串 "TSET".
文件如下所示:
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
所以在每个W之后"tset1";我需要添加一个新行:
模式 0:
提前感谢您的提示。
使用一个标志来确定先前遍历的行是否包含所需的字符串,然后使用条件。
#!/usr/bin/perl
use strict;
use warnings;
my $flag;
while (<DATA>){
chomp;
print $_;
$flag = 0;
if ($_ =~ /TSET/){
$flag = 1;
}
print "\ntset0:\n" if $flag;
}
__DATA__
lorem posum lorem posum lorem posum TSET lorem posu
lorem posulorem posu lorem posulorem posu lorem posu
lorem posuTSET
您的描述不太清楚 - 您是在搜索 tset 还是 TSET?您是用 tset0 还是 Pattern0 替换它?
但这似乎很简单。您应该可以根据自己的需要进行调整。
#!/usr/bin/perl
use strict;
use warnings;
my $count = 0;
while (<>) {
if (/TSET/) {
print "Pattern$count:\n"
++$count;
}
print;
}
它从 STDIN 读取并写入 STDOUT。所以你可以这样称呼它:
$ ./this_script.pl < your_input.dat > new_version.dat
我已将您文件的给定内容复制到我 PC 本地的文本文件中,并执行以下脚本。
#!C:\Strawberry\perl\bin
use strict;
use warnings;
my $file = "C:/Users/hclabv/Desktop/Data.txt";
#Opening file to get the required data
my $pattern = 0;
open (FILE, "$file");
while (<FILE>) {
my $CurrentLine = $_;
#Creating new file
open (FILE1, ">>NewData.txt");
print FILE1 "$CurrentLine";
if ($_ =~ /tset/) {
my $NewLine = "Pattern $pattern";
print FILE1 "$NewLine\n";
++$pattern;
}
close(FILE1);
}
close(FILE);
exit;
OUTPUT:生成的新文件(NewData.txt)具有以下数据。
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
Pattern 0
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
Pattern 1
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
如果您想在脚本执行时输入,请使用以下内容。
#!C:\Strawberry\perl\bin
use strict;
use warnings;
use File::Copy;
#Getting input file name
my $file = shift;
#just renaming the file
my $newfile = $file.".txt";
move($file,$newfile);
chomp($newfile);
#Opening file to get the required data
my $pattern = 0;
open (FIL, "$newfile");
while (<FIL>) {
my $CurrentLine = $_;
#Creating new file
open (FILE1, ">>$file");
print FILE1 "$CurrentLine";
if ($_ =~ /tset/) {
my $NewLine = "Pattern $pattern";
print FILE1 "$NewLine\n";
++$pattern;
}
close(FILE1);
}
close(FIL);
exit;
OUTPUT:将使用您在脚本执行时提供的相同文件名创建。在这里,我在 CMD 提示符下给出了以下文件名。
>perl pat.pl Data.txt
生成的 Data.txt 文件具有以下输出。
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
Pattern 0
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
Pattern 1
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
如果您使用的是基于 unix 的服务器,那么这可以写在一行中。
cat test_file.txt | perl -ne 'print /^(W "tset1";)$/ ? "\npattern" . $count++ . ":\n" : "$_"'
但是为了更好的布局和注释,我已经放在脚本中
use strict;
use warnings;
#take the file name from input and open it and initalise the counter as 0
my $file = shift || die "you need to give an input file";
open (my $fh, '<', $file) or die "Unable to open $file: $!";
my $count = 0;
#process each line and if the line matches our pattern tag on a new line and the pattern task to it otherwise just print the normal line.
while (<$fh>){
print /^(W "tset1";)$/ ? "\npattern" . $count++ . ":\n" : "$_";
}
我在使用 Perl 时遇到了一些麻烦。对如何进行这个非常简单的搜索感到绝望,然后在匹配后添加一个新行。
例如,在我的文件中,我将搜索一个名为 "TSET" 的重复字符串,然后在该行之后我将不得不添加一个不同的标签,比如 "tset0:"(当然是在新行中)并且它需要为下一个匹配增加 "tset1:" 但它始终是相同的搜索字符串 "TSET".
文件如下所示:
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
所以在每个W之后"tset1";我需要添加一个新行: 模式 0:
提前感谢您的提示。
使用一个标志来确定先前遍历的行是否包含所需的字符串,然后使用条件。
#!/usr/bin/perl
use strict;
use warnings;
my $flag;
while (<DATA>){
chomp;
print $_;
$flag = 0;
if ($_ =~ /TSET/){
$flag = 1;
}
print "\ntset0:\n" if $flag;
}
__DATA__
lorem posum lorem posum lorem posum TSET lorem posu
lorem posulorem posu lorem posulorem posu lorem posu
lorem posuTSET
您的描述不太清楚 - 您是在搜索 tset 还是 TSET?您是用 tset0 还是 Pattern0 替换它?
但这似乎很简单。您应该可以根据自己的需要进行调整。
#!/usr/bin/perl
use strict;
use warnings;
my $count = 0;
while (<>) {
if (/TSET/) {
print "Pattern$count:\n"
++$count;
}
print;
}
它从 STDIN 读取并写入 STDOUT。所以你可以这样称呼它:
$ ./this_script.pl < your_input.dat > new_version.dat
我已将您文件的给定内容复制到我 PC 本地的文本文件中,并执行以下脚本。
#!C:\Strawberry\perl\bin
use strict;
use warnings;
my $file = "C:/Users/hclabv/Desktop/Data.txt";
#Opening file to get the required data
my $pattern = 0;
open (FILE, "$file");
while (<FILE>) {
my $CurrentLine = $_;
#Creating new file
open (FILE1, ">>NewData.txt");
print FILE1 "$CurrentLine";
if ($_ =~ /tset/) {
my $NewLine = "Pattern $pattern";
print FILE1 "$NewLine\n";
++$pattern;
}
close(FILE1);
}
close(FILE);
exit;
OUTPUT:生成的新文件(NewData.txt)具有以下数据。
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
Pattern 0
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
Pattern 1
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
如果您想在脚本执行时输入,请使用以下内容。
#!C:\Strawberry\perl\bin
use strict;
use warnings;
use File::Copy;
#Getting input file name
my $file = shift;
#just renaming the file
my $newfile = $file.".txt";
move($file,$newfile);
chomp($newfile);
#Opening file to get the required data
my $pattern = 0;
open (FIL, "$newfile");
while (<FIL>) {
my $CurrentLine = $_;
#Creating new file
open (FILE1, ">>$file");
print FILE1 "$CurrentLine";
if ($_ =~ /tset/) {
my $NewLine = "Pattern $pattern";
print FILE1 "$NewLine\n";
++$pattern;
}
close(FILE1);
}
close(FIL);
exit;
OUTPUT:将使用您在脚本执行时提供的相同文件名创建。在这里,我在 CMD 提示符下给出了以下文件名。
>perl pat.pl Data.txt
生成的 Data.txt 文件具有以下输出。
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
Pattern 0
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 1XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 000 XXX XXX XX ; }
V { allFuncPins = 0XXX0X XX0XXX 100 011 XXX XX ; }
// pattern 0
W "tset1";
Pattern 1
V { allFuncPins = XXXXXX XXXXXX 110 011 XXX XX ; }
V { allFuncPins = XXXXXX 011000 111 011 XXX XX ; }
V { allFuncPins = XXXXXX 000000 111 011 XXX XX ; }
如果您使用的是基于 unix 的服务器,那么这可以写在一行中。
cat test_file.txt | perl -ne 'print /^(W "tset1";)$/ ? "\npattern" . $count++ . ":\n" : "$_"'
但是为了更好的布局和注释,我已经放在脚本中
use strict;
use warnings;
#take the file name from input and open it and initalise the counter as 0
my $file = shift || die "you need to give an input file";
open (my $fh, '<', $file) or die "Unable to open $file: $!";
my $count = 0;
#process each line and if the line matches our pattern tag on a new line and the pattern task to it otherwise just print the normal line.
while (<$fh>){
print /^(W "tset1";)$/ ? "\npattern" . $count++ . ":\n" : "$_";
}