开发者

perl -pe to manipulate filenames

I was trying to do some quick filename cleanup at the shell (zsh, if it matters). Renaming files. (I'm using cp instead of mv just to be safe)

foreach f (\#*.o开发者_JAVA百科gg)
  cp $f `echo $f | perl -pe 's/\#\d+ (.+)$/"\1"/'`
end

Now, I know there are tools to do stuff like this, but for personal interest I'm wondering how I can do it this way. Right now, I get an error:

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

Where 'When.ogg' is the last part of the filename. I've tried adding quotes (see above) and escaping the spaces, but nonetheless this is what I get.

Is there a reason I can't use the output of s perl pmr=;omrt as the final argument to another command line tool?


It looks like you have a space in the file names being processed, so each of your cp command lines evaluates to something like

cp \#nnnn When.Ogg When.ogg

When the cp command sees more than two arguments, the last one must be a target directory name for all the files to be copied to - hence the error message. Because your source filename ($f) contains a space it is being treated as two arguments - cp sees three args, rather than the two you intend.

If you put double quotes around the first $f that should prevent the two 'halves' of the name from being treated as separate file names:

cp "$f" `echo ...


This is what you need in bash, hope it's good for zsh too.

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

If the filename contains spaces, you also have quote the second argument of cp.


I often use

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

The -l chomps the input.

The -e check is to avoid accidentally renaming all the files to one name. I've done that a couple of times.

In bash (and I'm guessing zsh), that would be

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

or

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

or

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

The last supports file names with newlines in them.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜