perl函数将文件名和目录名中的所有空格替换为句点
我不是程序员,所以我只是想把免责声明放在那里。也许有更好的方法,但这是我开始的方式,我想知道为什么这不起作用 我有一个perl函数,用于将文件名和目录中的空格替换为句点:perl函数将文件名和目录名中的所有空格替换为句点,perl,Perl,我不是程序员,所以我只是想把免责声明放在那里。也许有更好的方法,但这是我开始的方式,我想知道为什么这不起作用 我有一个perl函数,用于将文件名和目录中的空格替换为句点: sub rm_space { for(@_) { # for directory or file if it contains spaces, replace with periods chomp; if(m/^(.*(.(?=\s).).*)$/) {
sub rm_space {
for(@_) {
# for directory or file if it contains spaces, replace with periods
chomp;
if(m/^(.*(.(?=\s).).*)$/) {
$new = $_;
$new =~ s/ /\./g;
move($_, $new);
}
if(-d) {
# if $_ is a directory, list contents and repeat
@arr = `ls -1d $_/*`;
rm_space(@arr);
}
}
}
该函数将处理第一个数组(@_)中的所有内容,但不会递归地处理第二个数组,除非第一个数组中的目录不包含空格
#!/usr/bin/env perl
use strict;
use warnings;
sub rm_space
{
foreach my $file_or_dir (@_) {
my $with_dots = $file_or_dir;
if ( $with_dots =~ tr/ /./ ) {
# only called when replacement occurred
rename( $file_or_dir, $with_dots );
}
if ( -d $with_dots ) {
my @arr = glob("$with_dots/*");
rm_space(@arr);
}
}
}
rm_space( glob("start_dir/*") );
您首先将目录从例如dir with spaces
重命名为dir.with.spaces
,然后深入到
带空格的dir
。那个目录已经不存在了。您需要两个变量,一个用于旧名称
一个用于新名称,然后对新名称调用rm\u space
另外,强烈建议使用strict代码>和使用警告代码>以避免常见错误(如打字错误
或使用未定义的变量)
我将对ls
的调用替换为对glob
的调用。优点是你不必在意
然后在名称中加空格。您的带有空格的ls-1d dir/*
一定失败了
我还使用了显式变量(与隐式的$\uu
相反),因为有时很难理解
实际包含的内容
您首先将目录从例如dir with spaces
重命名为dir.with.spaces
,然后深入到
带空格的dir
。那个目录已经不存在了。您需要两个变量,一个用于旧名称
一个用于新名称,然后对新名称调用rm\u space
另外,强烈建议使用strict代码>和使用警告代码>以避免常见错误(如打字错误
或使用未定义的变量)
我将对ls
的调用替换为对glob
的调用。优点是你不必在意
然后在名称中加空格。您的带有空格的ls-1d dir/*
一定失败了
我还使用了显式变量(与隐式的$\uu
相反),因为有时很难理解
实际包含的内容。要在Perl中递归处理文件,请使用:
要在Perl中递归处理文件,请使用:
我真的看不出你的和我的有什么不同。。。这部分也不是问题,你说得对。但现在我想我发现了错误:在第一个中,如果将目录从dir1
重命名为dir.1
,然后使用旧名称执行ls-1d dir1
。但那个目录已经不存在了。另外:ls-1d dir 1
如果目录名中有空格,它将不起作用。你没有错误吗?我没有错误,是的,我也这么想。那么,第一步($新,$)不会立即生效吗?因为我认为当计算第二个if时,目录将被重命名并反映在第二个数组中。我假设情况并非如此,我想知道我是否能做到。魔法/隐藏/自动变量$上的-d
仍然有效,这一点没有改变。稍等。Is$new=~$密码>打字错误?我真的看不出你的和我的有什么区别。。。这部分也不是问题,你说得对。但现在我想我发现了错误:在第一个中,如果将目录从dir1
重命名为dir.1
,然后使用旧名称执行ls-1d dir1
。但那个目录已经不存在了。另外:ls-1d dir 1
如果目录名中有空格,它将不起作用。你没有错误吗?我没有错误,是的,我也这么想。那么,第一步($新,$)不会立即生效吗?因为我认为当计算第二个if时,目录将被重命名并反映在第二个数组中。我假设情况并非如此,我想知道我是否能做到。魔法/隐藏/自动变量$上的-d
仍然有效,这一点没有改变。稍等。Is$new=~$代码>输入错误?我以为我有,但我不知道你的例子似乎是最好的。谢谢你为我简化了它!我以为我有,但我不知道你的例子似乎是最好的。谢谢你为我简化了它!
#!/usr/bin/perl
use warnings;
use strict;
use File::Find;
my %rename;
find(\&spaces2dots, shift);
for my $old (sort { length $b <=> length $a } keys %rename) {
rename $old, $rename{$old}
or warn "Cannot rename $old to $rename{$old}.\n";
}
sub spaces2dots {
( my $new = $File::Find::name ) =~ s{ (?!.*/)}{.}g;
$rename{$File::Find::name} = $new;
}
run: clean
mkdir 'a b' 'c d'
mkdir 'a b'/'A B' 'a b'/'C D'
mkdir 'a b'/'C D'/'e F'
touch 'e f' 'a b'/'E F' 'a b'/'C D'/'e F'/'g H'
40115711.pl .
find
clean:
rm -rf ???