需要遍历Unix目录并搜索每个文件中的每一行。如果存在模式匹配,请删除该行。无法删除行,所以我只是试图找到模式并替换为另一个。
使用文件名填充数组并进行遍历。我有一个计数器,它正在查看每个文件中的每一行(至少它们计数正确)。
#!/usr/bin/perl -l
#!/usr/bin/perl -i.bak -w
#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
# 4-1-19
# pfs
# remove lines with dental code ADD2999 from all HMO Max load files in /home/hsxxx/dat/feeLoad directory
$| = 1;
chdir "/home/hstrn/dat/feeLoad";
chdir;
my $dir = </home/hstrn/dat/feeLoad/>;
my @files;
my $count=0;
opendir(DIR, $dir) or die "Cannot open directory $dir, Perl says $!\n";
while (my $file = readdir DIR)
{
push @files, "$dir/$file" unless -d "$dir/$file";
}
closedir DIR;
{
local @ARGV = @files;
while (<>)
{
s/ADD2999/sometext/g;
$count++;
}
print "Total lines read are: $count";
}
希望所有字符串ADD2999都被替换为文本
答案 0 :(得分:2)
要删除行,需要在写入新文件时避免打印它们。您的代码根本不会写入任何文件?
这可能是现有工具的工作。
find /home/hstrn/dat/feeLoad -maxdepth 1 -type f \
-exec perl -i~ -ne'print if !/ADD2999/' {} +
如果要避免创建备份,请使用-i
代替-i~
。我更喜欢创建备份,然后在确认一切正常后将其删除。
显示将要删除的文件:
find /home/hstrn/dat/feeLoad -maxdepth 1 -type f -name '*~'
删除文件:
find /home/hstrn/dat/feeLoad -maxdepth 1 -type f -name '*~' -delete
答案 1 :(得分:0)
这是我第一次尝试解决该问题,但是它可能会使用更多的极端情况检查。例如。您如何处理受写保护的文件等。它还假定文件足够小,可以放入内存进行处理。
#!/usr/bin/perl
use warnings;
use strict;
use autodie;
use File::Spec;
use File::Slurper qw(read_text write_text);
my $count = 0;
my $dir = "tmp";
opendir(my $dh, $dir);
while (readdir $dh) {
# skip anything that shouldn't be processed
next if /^\.\.?$/; # . && ..
my $file = File::Spec->catfile($dir, $_);
next if -d $file; # directories
# slurp file content and replace text
my $content = read_text($file);
my $matches = ($content =~ s/ADD2999/sometext/g);
# count lines
my @eols = ($content =~ /(\n)/g);
$count += @eols;
# replace original file if contents were modified
write_text($file, $content) if $matches;
}
closedir($dh);
print "Total lines read are: $count\n";
exit 0;
试运行:
$ wc -l tmp/test*.txt
5 tmp/test2.txt
6 tmp/test.txt
11 total
$ fgrep ADD2999 tmp/*.txt
tmp/test2.txt:asddsada ADD2999 asdsadasd
tmp/test2.txt:21312398 ADD2999 dasdas
$ perl dummy.pl
Total lines read are: 11
$ fgrep ADD2999 tmp/*.txt
$ fgrep sometext tmp/*.txt
tmp/test2.txt:asddsada sometext asdsadasd
tmp/test2.txt:21312398 sometext dasdas
如果文件很大,则需要使用逐行处理方法(仅显示循环的内容)。副作用是所有文件都会被触摸,尽管其中可能没有任何替换内容。
# read file and replace text
open(my $ifh, '<', $file);
my $tmpfile = File::Spec->catfile($dir, "$_.$$");
open(my $ofh, '>', $tmpfile);
while (<$ifh>) {
s/ADD2999/sometext/g;
print $ofh $_;
}
$count += $.; # total lines in $ifh
close($ofh);
close($ifh);
# replace original file with new file
unlink($file);
rename($tmpfile, $file);