[英]How to recursively change files in directories whose name matches a string in Perl?
I have many directories for different projects. 我有许多不同项目的目录。 Under some project directories, there are subdirectories named "matlab_programs".
在某些项目目录下,有一些名为“ matlab_programs”的子目录。 In only subdirectories named matlab_programs, I would like to replace the string 'red' with 'blue' in files ending with *.m.
在仅名为matlab_programs的子目录中,我想在以* .m结尾的文件中将字符串“ red”替换为“ blue”。
The following perl code will recursively replace the strings in all *.m files, regardless of what subdirectories the files are in. 以下perl代码将以递归方式替换所有* .m文件中的字符串,而不管文件位于哪个子目录中。
find . -name "*.m" | xargs perl -p -i -e "s/red/blue/g"
And to find the full paths of all directories called matlab_programs, 要找到所有名为matlab_programs的目录的完整路径,
find . -type d -name "matlab_programs"
How can I combine these so I only replace strings if the files are in a subdirectory called matlab_programs? 如何合并这些内容,以便仅在文件位于名为matlab_programs的子目录中时替换字符串?
Perl has the excellent File::Find
module, that lets you specify a callback to be called on each file. Perl具有出色的
File::Find
模块,该模块可让您指定要在每个文件上调用的回调。
So you can specified a complex compound criteria, like this: 因此,您可以指定一个复杂的复合条件,如下所示:
#!/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, "." );
And then you can do whatever you wish with the files you find - like opening/text replacing and closing. 然后,您可以对找到的文件进行任何操作,例如打开/替换和关闭文本。
Do you have bash
? 你有
bash
吗? The $(...)
syntax works like backticks (the way both the shell and Perl use them) but they can be nested. $(...)
语法的作用类似于反引号(shell和Perl都使用反引号的方式),但是它们可以嵌套。
perl -pi -e s/red/blue/g $(find $(find . -type d -name matlab_programs) -type f -name \*.m)
Many flavors of find
also support a -path pattern
test, so you can just combine your filename conditions into that argument 许多类型的
find
也支持-path pattern
测试,因此您可以将文件名条件组合到该参数中
perl -pi -e s/red/blue/g $(find . -type f -path \*/matlab_programs/\*.m)
You want to find all directories named matlab_programs
using 您想使用以下命令找到所有名为
matlab_programs
目录
find . -type d -name "matlab_programs"
and then execute 然后执行
find $f -name "*.m" | xargs perl -p -i -e "s/red/blue/g"
on all results $f
. 在所有结果
$f
。 Judging by your use of xargs
, there are no special characters such as spaces in your file names. 通过使用
xargs
判断,文件名中没有特殊字符,例如空格。 so the following should work: 所以以下应该工作:
find `find . -type d -name "matlab_programs"` -name "*.m" |
xargs perl -p -i -e "s/red/blue/g"
or 要么
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"
Incidentally, I'd use single quotes here; 顺便说一句,我在这里使用单引号。 I always use them whenever the quoted string is to be taken literally.
每当引号字符串按字面意义使用时,我总是使用它们。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.