如何递归更改名称与 Perl 中的字符串匹配的目录中的文件?
How to recursively change files in directories whose name matches a string in Perl?
我有很多不同项目的目录。在某些项目目录下,有名为"matlab_programs"的子目录。在仅名为 matlab_programs 的子目录中,我想在以 *.m.
结尾的文件中将字符串 'red' 替换为 'blue'
以下 perl 代码将递归替换所有 *.m 文件中的字符串,无论这些文件位于哪个子目录中。
find . -name "*.m" | xargs perl -p -i -e "s/red/blue/g"
并查找名为 matlab_programs、
的所有目录的完整路径
find . -type d -name "matlab_programs"
如果文件位于名为 matlab_programs 的子目录中,我该如何组合它们以便仅替换字符串?
Perl 具有出色的 File::Find
模块,它允许您指定要在每个文件上调用的回调。
因此您可以指定一个复杂的复合条件,如下所示:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
sub find_files {
next unless m/\.m\z/; # skip any files that don't end in .m
if ( $File::Find::dir =~ m/matlab_programs$/ ) {
print $File::Find::name, " found\n";
}
}
find( \&find_files, "." );
然后您可以对找到的文件做任何您想做的事情 - 例如 opening/text 替换和关闭。
你有bash
吗? $(...)
语法像反引号一样工作(shell 和 Perl 使用它们的方式)但它们可以嵌套。
perl -pi -e s/red/blue/g $(find $(find . -type d -name matlab_programs) -type f -name \*.m)
find
的许多版本也支持 -path pattern
测试,因此您可以将文件名条件组合到该参数中
perl -pi -e s/red/blue/g $(find . -type f -path \*/matlab_programs/\*.m)
您想使用
查找所有名为 matlab_programs
的目录
find . -type d -name "matlab_programs"
然后执行
find $f -name "*.m" | xargs perl -p -i -e "s/red/blue/g"
所有结果 $f
。从您使用 xargs
判断,您的文件名中没有空格等特殊字符。所以以下应该有效:
find `find . -type d -name "matlab_programs"` -name "*.m" |
xargs perl -p -i -e "s/red/blue/g"
或
find . -type d -name "matlab_programs" |
while read f
do
find $f -name "*.m" | xargs perl -p -i -e "s/red/blue/g"
done |
xargs perl -p -i -e "s/red/blue/g"
顺便说一句,我在这里使用单引号;每当要按字面意思理解引用的字符串时,我总是使用它们。
我有很多不同项目的目录。在某些项目目录下,有名为"matlab_programs"的子目录。在仅名为 matlab_programs 的子目录中,我想在以 *.m.
结尾的文件中将字符串 'red' 替换为 'blue'以下 perl 代码将递归替换所有 *.m 文件中的字符串,无论这些文件位于哪个子目录中。
find . -name "*.m" | xargs perl -p -i -e "s/red/blue/g"
并查找名为 matlab_programs、
的所有目录的完整路径find . -type d -name "matlab_programs"
如果文件位于名为 matlab_programs 的子目录中,我该如何组合它们以便仅替换字符串?
Perl 具有出色的 File::Find
模块,它允许您指定要在每个文件上调用的回调。
因此您可以指定一个复杂的复合条件,如下所示:
#!/usr/bin/env perl
use strict;
use warnings;
use File::Find;
sub find_files {
next unless m/\.m\z/; # skip any files that don't end in .m
if ( $File::Find::dir =~ m/matlab_programs$/ ) {
print $File::Find::name, " found\n";
}
}
find( \&find_files, "." );
然后您可以对找到的文件做任何您想做的事情 - 例如 opening/text 替换和关闭。
你有bash
吗? $(...)
语法像反引号一样工作(shell 和 Perl 使用它们的方式)但它们可以嵌套。
perl -pi -e s/red/blue/g $(find $(find . -type d -name matlab_programs) -type f -name \*.m)
find
的许多版本也支持 -path pattern
测试,因此您可以将文件名条件组合到该参数中
perl -pi -e s/red/blue/g $(find . -type f -path \*/matlab_programs/\*.m)
您想使用
查找所有名为matlab_programs
的目录
find . -type d -name "matlab_programs"
然后执行
find $f -name "*.m" | xargs perl -p -i -e "s/red/blue/g"
所有结果 $f
。从您使用 xargs
判断,您的文件名中没有空格等特殊字符。所以以下应该有效:
find `find . -type d -name "matlab_programs"` -name "*.m" |
xargs perl -p -i -e "s/red/blue/g"
或
find . -type d -name "matlab_programs" |
while read f
do
find $f -name "*.m" | xargs perl -p -i -e "s/red/blue/g"
done |
xargs perl -p -i -e "s/red/blue/g"
顺便说一句,我在这里使用单引号;每当要按字面意思理解引用的字符串时,我总是使用它们。