如何检查文件内容并根据检查条件,添加或更新文件?
How to check file content and depending on check condition, prepend or update the the file?
我是 Perl 的新手,我需要编写一个 Perl 脚本来执行以下操作:
- 递归地遍历一个目录,只处理具有特定扩展名(例如 .txt)的文件。
- 对于每个 .txt 文件,我需要在文件前添加一个 header,或者如果 header 已经存在则更新 header。
header 看起来像这样:
//-----------------------------------------//
Model : Info1
Date : Info2
Name : Info3
//-----------------------------------------//
到目前为止我做了什么:
use File::Find;
use Cwd qw(getcwd);
use strict;
sub gen_header {
my $divider = "//------------------------------------//\n";
my $time = localtime();
my $modelpath = getcwd();
my $user = (getpwuid($<))[0];
my $header;
$header .= $divider;
$header .= "//Model : $modelpath\n";
$header .= "//Date : $time\n";
$header .= "//Name : $user\n";
$header .= $divider;
$header .= "\n";
return header;
}
my $dir = "/src/dir1";
find (\&process_file, $dir);
sub process_file {
my $filename = $_;
my $out_file = $_.out;
if (-f and /\.(txt)$/) {
open (my $fh1, "<", $filename) || die "ERROR";
open (my $fh2, ">", $out_file) || die "ERROR";
if (*header already exist*) {
#Update header
*code to update Info1, Info2 and Info3 in the header;*
} else {
#Prepend the header
print $fh2 gen_header();
while (<$fh1>) {
print $fh2 $_;
}
}
close $fh2;
rename ($out_file, $filename) or die "Rename error";
}
}
我已经设法创建了一个子例程来生成所需的 header,我相信我递归遍历目录和处理文件的方式是正确的。不过,我无法弄清楚在那之后如何更新 header 。所以问题,
- 如何执行代码的“更新 header”部分? gen_header 子例程 returns 一个新的 header 每次它的 运行 都有最新的信息但是我如何使用它来替换旧的 header?
- 我递归遍历目录和处理文件的方式是否正确,或者是否有更好的方法来做我想做的事情?
我不能说得更具体,因为我没有看到你是如何获得你的 'header' 详细信息的。
然而,根据您目前提供的内容:
How do I do the "update header" part of the code? The gen_header subroutine returns a new header with the latest info every time its run but how do I use it to replace the old header?
你说过你要更新一个header,所以我假设它已经存在了。
但是:
open ( my $input, '<', "existing_file" ) or die $!;
open ( my $output, '>', "new_file" ) or die $!;
select $output;
print $my_new_header; # will go to $output
my $seen;
while ( <$input> ) {
m,//-----, && $seen++;
#this will skip until the second instance of '//-----' in your file,
# so it'll 'eat' the whole file if there's no header at all.
next unless $seen >= 2;
print;
}
或者,如果您可以可靠地检测到 header 的存在,您可以对 search-and-replace 执行相同的方法:
while ( <$input> ) {
s/Model\s+: .*/Model : $my_model/;
# etc.
print;
}
注意:如果您的开始和结束标记略有不同,您可以使用 if ( m,//---, .. m,//--, ) {
类型语法,但如果两个匹配项相同,这将不起作用。
Is the way I am traversing a directory recursively and processing files correct or is there a better way to do what I want?
File::Find 是完成这项工作的工具,您正在做的很好。
虽然您正在不必要地捕获 (txt)
,但这是一件相当小的事情。
if (-f and /\.(txt)$/) {
除非您出于某种原因需要 </code> 来包含 'txt',为清楚起见,您最好使用 <code>/\.txt$/
。
我是 Perl 的新手,我需要编写一个 Perl 脚本来执行以下操作:
- 递归地遍历一个目录,只处理具有特定扩展名(例如 .txt)的文件。
- 对于每个 .txt 文件,我需要在文件前添加一个 header,或者如果 header 已经存在则更新 header。
header 看起来像这样:
//-----------------------------------------//
Model : Info1
Date : Info2
Name : Info3
//-----------------------------------------//
到目前为止我做了什么:
use File::Find;
use Cwd qw(getcwd);
use strict;
sub gen_header {
my $divider = "//------------------------------------//\n";
my $time = localtime();
my $modelpath = getcwd();
my $user = (getpwuid($<))[0];
my $header;
$header .= $divider;
$header .= "//Model : $modelpath\n";
$header .= "//Date : $time\n";
$header .= "//Name : $user\n";
$header .= $divider;
$header .= "\n";
return header;
}
my $dir = "/src/dir1";
find (\&process_file, $dir);
sub process_file {
my $filename = $_;
my $out_file = $_.out;
if (-f and /\.(txt)$/) {
open (my $fh1, "<", $filename) || die "ERROR";
open (my $fh2, ">", $out_file) || die "ERROR";
if (*header already exist*) {
#Update header
*code to update Info1, Info2 and Info3 in the header;*
} else {
#Prepend the header
print $fh2 gen_header();
while (<$fh1>) {
print $fh2 $_;
}
}
close $fh2;
rename ($out_file, $filename) or die "Rename error";
}
}
我已经设法创建了一个子例程来生成所需的 header,我相信我递归遍历目录和处理文件的方式是正确的。不过,我无法弄清楚在那之后如何更新 header 。所以问题,
- 如何执行代码的“更新 header”部分? gen_header 子例程 returns 一个新的 header 每次它的 运行 都有最新的信息但是我如何使用它来替换旧的 header?
- 我递归遍历目录和处理文件的方式是否正确,或者是否有更好的方法来做我想做的事情?
我不能说得更具体,因为我没有看到你是如何获得你的 'header' 详细信息的。
然而,根据您目前提供的内容:
How do I do the "update header" part of the code? The gen_header subroutine returns a new header with the latest info every time its run but how do I use it to replace the old header?
你说过你要更新一个header,所以我假设它已经存在了。
但是:
open ( my $input, '<', "existing_file" ) or die $!;
open ( my $output, '>', "new_file" ) or die $!;
select $output;
print $my_new_header; # will go to $output
my $seen;
while ( <$input> ) {
m,//-----, && $seen++;
#this will skip until the second instance of '//-----' in your file,
# so it'll 'eat' the whole file if there's no header at all.
next unless $seen >= 2;
print;
}
或者,如果您可以可靠地检测到 header 的存在,您可以对 search-and-replace 执行相同的方法:
while ( <$input> ) {
s/Model\s+: .*/Model : $my_model/;
# etc.
print;
}
注意:如果您的开始和结束标记略有不同,您可以使用 if ( m,//---, .. m,//--, ) {
类型语法,但如果两个匹配项相同,这将不起作用。
Is the way I am traversing a directory recursively and processing files correct or is there a better way to do what I want?
File::Find 是完成这项工作的工具,您正在做的很好。
虽然您正在不必要地捕获 (txt)
,但这是一件相当小的事情。
if (-f and /\.(txt)$/) {
除非您出于某种原因需要 </code> 来包含 'txt',为清楚起见,您最好使用 <code>/\.txt$/
。