perl -pe来操作文件名

时间:2011-08-15 21:15:06

标签: perl shell

我试图在shell上做一些快速的文件名清理(zsh,如果重要的话)。重命名文件。 (我使用cp代替mv只是为了安全)

foreach f (\#*.ogg)
  cp $f `echo $f | perl -pe 's/\#\d+ (.+)$/"\1"/'`
end

现在,我知道有工具可以做这样的事情,但出于个人兴趣,我想知道我怎么能这样做。现在,我收到一个错误:

cp: target `When.ogg"' is not a directory

其中'When.ogg'是文件名的最后一部分。我尝试添加引号(见上文)并转义空格,但这仍然是我得到的。

有没有理由我不能使用s perl的输出pmr =; omrt作为另一个命令行工具的最后一个参数?

3 个答案:

答案 0 :(得分:1)

看起来您正在处理的文件名中有一个空格,因此每个cp命令行的计算结果都是

cp \#nnnn When.Ogg When.ogg

当cp命令看到两个以上的参数时,最后一个参数必须是要复制到的所有文件的目标目录名 - 因此出现错误消息。因为你的源文件名($f)包含一个空格,所以它被视为两个参数 - cp看到三个 args,而不是你想要的两个。

如果在 first $ f周围加上双引号,应该防止名称的两个“一半”被视为单独的文件名:

cp "$f" `echo ...

答案 1 :(得分:0)

这就是你在bash中所需要的,希望它对zsh也有好处。

cp "$f" "`echo $f | perl -pe 's/\#\d+ (.+)$/\1/'`"

如果文件名包含空格,则还引用cp的第二个参数。

答案 2 :(得分:0)

我经常使用

dir /b ... | perl -nle"$o=$_; s/.../.../; $n=$_; rename $o,$n if !-e $n"

-l会选择输入。

-e检查是为了避免意外地将所有文件重命名为一个名称。我做过几次。

在bash中(我猜zsh),那就是

foreach f (...)
   echo "$f" | perl -nle'$o=$_; s/.../.../; $n=$_; rename $o,$n if !-e $n'
end

find -name '...'  -maxdepth 1 \
   | perl -nle'$o=$_; s/.../.../; $n=$_; rename $o,$n if !-e $n'

find -name '...'  -maxdepth 1 -exec \
   perl -e'for (@ARGV) {
      $o=$_; s/.../.../; $n=$_;
      rename $o,$n if !-e $n;
   }' {} +

最后一个支持带有换行符的文件名。