Regex 使用perl脚本就地修改文件中读取的行
我有一个文件,作为Regex 使用perl脚本就地修改文件中读取的行,regex,perl,scripting,Regex,Perl,Scripting,我有一个文件,作为ARGV[0]或参数传递给我的perl脚本。此文件包含我将读取并修改单个文件中的行的文件列表。我想就地修改这些文件,而不是写入新文件 代码是这样的:- use strict; use warnings; use FindBin; use English; use File::Path; my $list=$ARGV[0]; open(my $WAY,'<:encoding(UTF-8)',$list) or die("could not open list
ARGV[0]
或参数传递给我的perl脚本。此文件包含我将读取并修改单个文件中的行的文件列表。我想就地修改这些文件,而不是写入新文件
代码是这样的:-
use strict;
use warnings;
use FindBin;
use English;
use File::Path;
my $list=$ARGV[0];
open(my $WAY,'<:encoding(UTF-8)',$list) or die("could not open list file");
foreach my $file(<$WAY>){
chomp($file);
open(my $ASCII,''<:encoding(UTF-8)',$file) or die("could not open list file");
foreach my $line (<$ASCII>){
chmop($line);
#####Here I do important stuff as per business requirement
## Now a array @coloumns stores all the values by which i need to
### replace this read line.
##This array element needs to be joined by ',' so basically i want
##to replace read line in-place by join(",",@coloumns,"\n");
}
}
使用严格;
使用警告;
使用FindBin;
使用英语;
使用File::Path;
my$list=$ARGV[0];
打开(我的$WAY,我包括两种方式:使用临时文件和使用下面的数组
但是,您确实希望使用temp file方法,因为它是原子的。使用array方法,如果系统在写回期间崩溃,您的文件将被销毁。temp file方法保证是原子的,如果发生崩溃,您的文件将不会被销毁
那么,你对临时文件有什么异议
use strict;
use warnings;
use FindBin;
use English;
use File::Path;
my $list=$ARGV[0];
open(my $WAY,'<:encoding(UTF-8)',$list) or
die("could not open list file -- '$list'\n");
foreach my $file (<$WAY>) {
chomp($file);
dotmp($file);
}
close($WAY);
sub dotmp
{
my($file) = @_;
my($oline);
open(my $INPUT,'<:encoding(UTF-8)',$file) or
die("could not open input file -- '$file'\n");
my($tmp) = $file . ".TMP";
open(my $OUTPUT,'>:encoding(UTF-8)',$tmp) or
die("could not open output file\n");
foreach my $line (<$INPUT>){
chomp($line);
#####Here I do important stuff as per business requirement
## Now a array @coloumns stores all the values by which i need to
### replace this read line.
##This array element needs to be joined by ',' so basically i want
##to replace read line in-place by join(",",@coloumns,"\n");
$oline = join(",",@coloumns);
print($OUTPUT $oline,"\n");
}
close($INPUT);
close($OUTPUT);
# NOTE: this is _atomic_ -- even if the system crashes, you'll either get
# the whole contents before or after but _never_ a partial mashup
rename($tmp,$file) or
die("unable to rename '$file' -- $!\n");
}
sub doarray
{
my($file) = @_;
my($oline);
my(@array);
open(my $INPUT,'<:encoding(UTF-8)',$file) or
die("could not open input file -- '$file'\n");
foreach my $line (<$INPUT>){
chomp($line);
#####Here I do important stuff as per business requirement
## Now a array @coloumns stores all the values by which i need to
### replace this read line.
##This array element needs to be joined by ',' so basically i want
##to replace read line in-place by join(",",@coloumns,"\n");
$oline = join(",",@coloumns);
push(@array,$oline);
}
close($INPUT);
open(my $OUTPUT,'>:encoding(UTF-8)',$file) or
die("could not open output file\n");
# NOTE: if the system crashes while doing this, the file will be corrupted
foreach $oline (@array) {
print($OUTPUT $oline,"\n");
}
close($OUTPUT);
}
使用严格;
使用警告;
使用FindBin;
使用英语;
使用File::Path;
my$list=$ARGV[0];
打开(我的$WAY,我包括两种方式:使用临时文件和使用下面的数组
但是,您确实希望使用temp file方法,因为它是原子的。使用array方法,如果系统在写回期间崩溃,您的文件将被销毁。temp file方法保证是原子的,如果发生崩溃,您的文件将不会被销毁
那么,你对临时文件有什么异议
use strict;
use warnings;
use FindBin;
use English;
use File::Path;
my $list=$ARGV[0];
open(my $WAY,'<:encoding(UTF-8)',$list) or
die("could not open list file -- '$list'\n");
foreach my $file (<$WAY>) {
chomp($file);
dotmp($file);
}
close($WAY);
sub dotmp
{
my($file) = @_;
my($oline);
open(my $INPUT,'<:encoding(UTF-8)',$file) or
die("could not open input file -- '$file'\n");
my($tmp) = $file . ".TMP";
open(my $OUTPUT,'>:encoding(UTF-8)',$tmp) or
die("could not open output file\n");
foreach my $line (<$INPUT>){
chomp($line);
#####Here I do important stuff as per business requirement
## Now a array @coloumns stores all the values by which i need to
### replace this read line.
##This array element needs to be joined by ',' so basically i want
##to replace read line in-place by join(",",@coloumns,"\n");
$oline = join(",",@coloumns);
print($OUTPUT $oline,"\n");
}
close($INPUT);
close($OUTPUT);
# NOTE: this is _atomic_ -- even if the system crashes, you'll either get
# the whole contents before or after but _never_ a partial mashup
rename($tmp,$file) or
die("unable to rename '$file' -- $!\n");
}
sub doarray
{
my($file) = @_;
my($oline);
my(@array);
open(my $INPUT,'<:encoding(UTF-8)',$file) or
die("could not open input file -- '$file'\n");
foreach my $line (<$INPUT>){
chomp($line);
#####Here I do important stuff as per business requirement
## Now a array @coloumns stores all the values by which i need to
### replace this read line.
##This array element needs to be joined by ',' so basically i want
##to replace read line in-place by join(",",@coloumns,"\n");
$oline = join(",",@coloumns);
push(@array,$oline);
}
close($INPUT);
open(my $OUTPUT,'>:encoding(UTF-8)',$file) or
die("could not open output file\n");
# NOTE: if the system crashes while doing this, the file will be corrupted
foreach $oline (@array) {
print($OUTPUT $oline,"\n");
}
close($OUTPUT);
}
使用严格;
使用警告;
使用FindBin;
使用英语;
使用File::Path;
my$list=$ARGV[0];
打开(我的$WAY,TLDR:aet的评论可能是最好的选择。文本文件通常不适合真正的就地编辑
你要找的绳子:
如果使用TLDR打开文件:aet的注释可能是最好的选择。文本文件通常不适合进行真正的就地编辑
你要找的绳子:
如果用+打开文件可能有点过火,但它可以满足您的需要。要构建@contents
,我只需在空白处拆分原始行
use warnings;
use strict;
use Tie::File;
my $list = $ARGV[0];
open my $way, '<:encoding(UTF-8)', $list or die $!;
while (my $file = <$way>){
chomp $file;
tie my @contents, 'Tie::File', $file or die $!;
for (@contents){
my @columns = split /\s+/, $_;
s/.*/join ', ', @columns/e;
}
untie @contents;
}
输出:
one, two, three
1, 2, 3
a, b, c
可能有点过火,但它可以满足您的需要。要构建@contents
,我只需在空白处拆分原始行
use warnings;
use strict;
use Tie::File;
my $list = $ARGV[0];
open my $way, '<:encoding(UTF-8)', $list or die $!;
while (my $file = <$way>){
chomp $file;
tie my @contents, 'Tie::File', $file or die $!;
for (@contents){
my @columns = split /\s+/, $_;
s/.*/join ', ', @columns/e;
}
untie @contents;
}
输出:
one, two, three
1, 2, 3
a, b, c
首先读取数据结构中的所有行,关闭文件,重新打开以进行写入,然后写出修改。或者先将文件转换为tmp文件,然后一次一行地执行。我不想创建临时文件,您能否提供一个示例如何执行此操作。首先读取数据结构中的所有行,关闭文件,重新打开以进行写入,然后执行以下操作:我不想做一个临时文件,你能提供一个如何做的例子吗?在Perl 5时代,领带的使用似乎已经有了。我个人不使用领带,但几年前我涉足过Tie::file。虽然当时我没有坚持使用它项目,这个想法仍然存在stuck@tjd在键/值对DBMs(如Berkeley DB)等方面,ties的用途有限。我在那天做了几次,只是为了让自己了解情况。在我看来,ties在跟踪bug方面很有用。如果某个变量在某个地方被某个东西损坏,并且无法使用调试器(例如,在实时生产系统中,腐败只会在N天后发生,并且有太多地方需要更改以在所有地方添加检查代码),您可以绑定变量,并让底层类执行您想要的任何复杂的观察点代码。在Perl 5时代,似乎已经使用了绑定。我个人不使用它们,但几年前我涉猎过了tie::File。尽管我在当时的项目中没有坚持使用它,但这个想法仍然存在stuck@tjd领带在日常生活中的作用有限ke键/值对DBMs(例如Berkeley DB)。我在那天做了几次,只是为了让我的脚湿一湿。在我看来,它们在跟踪bug方面很有用。如果你在某个地方发现某个变量被某个东西损坏,并且无法使用调试器(例如,在实时生产系统中,只有N天后才会发生损坏,并且有太多的地方会更改为到处添加检查代码),您可以绑定变量并让基础类执行您想要的任何复杂的观察点代码。我喜欢此处提供的细节。:)我喜欢此处提供的细节。:)对于数组方法,我们至少可以减少对文件的写入次数:print$OUTPUT join(“\n”,@array),“\n”
@glennjackman数组方法只是为了完整性,但出于我提到的原因,不推荐使用。即使它可以在单个[大型]中完成写,这仍然是一个危险。我已经有一段时间没有把它放在板凳上了,但是因为perlforeach
迭代器非常快,而且perlio的速度非常快,循环可能比join
更快,因为它不必创建中间[隐式]标量。join
仍将在perlio
[这将把它分割成更小的write(2)
调用],因此与其说是加速,不如说是一种[语法]便利。@glennjackman我在不同的时间都不得不这样做。fc22的perl破坏了我的脚本[他们的错]。我还通过安装一个过滤器(请参见perldoc-f require
)在我的perl上用perl进行元编程。我像cpp
for C那样使用它来添加/删除调试代码。这必须很快[在加载过程中会增加开销],我坐在凳子上,发现while($x=){chomp($x);push(@a,$x);}
beats@a=;chomp(@a)
每次。既然这是一个(好的)一般性建议,为什么不为临时文件使用更健壮的命名?例如,通过使用file::temp qw(tempfile)
,或诸如此类。是一个核心模块。对于数组方法,我们至少可以减少写入文件的次数:打印$OUTPUT join(“\n”,@array),“\n”
@glennjackman数组方法只是为了完整性,但由于我提到的原因,不推荐使用。即使它可以在一次[大规模]写入中完成,它仍然是一种危险。我已经有一段时间没有将其固定,但因为