在 bash 中使用正则表达式复制和重命名多个文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14859345/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 04:33:31  来源:igfitidea点击:

Copy and Rename Multiple Files with Regular Expressions in bash

regexbashcopyrename

提问by jlconlin

I've got a file structure that looks like:

我有一个看起来像这样的文件结构:

A/
    2098765.1ext
    2098765.2ext
    2098765.3ext
    2098765.4ext
      12345.1ext
      12345.2ext
      12345.3ext
      12345.4ext

B/
    2056789.1ext
    2056789.2ext
    2056789.3ext
    2056789.4ext
      54321.1ext
      54321.2ext
      54321.3ext
      54321.4ext

I need to rename all the files that begin with 20to start with 10; i.e., I need to rename B/2022222.1extto B/1022222.1ext

我需要重命名20以开头的所有文件10;即,我需要重命名B/2022222.1extB/1022222.1ext

I've seen many of the other questions regarding renaming multiple files, but couldn't seem to make it work for my case. Just to see if I can figure out what I'm doing before I actually try to do the copy/renaming I've done:

我已经看到许多有关重命名多个文件的其他问题,但似乎无法使其适用于我的情况。只是想看看我是否能在我实际尝试进行复制/重命名之前弄清楚我在做什么:

for file in "*/20?????.*"; do
    echo "{$file/20/10}";
done

but all I get is

但我得到的只是

{*/20?????.*/20/10}

Can someone show me how to do this?

有人可以告诉我如何做到这一点吗?

回答by Explosion Pills

You just have a little bit of incorrect syntax is all:

你只是有一点不正确的语法:

for file in */20?????.*; do mv $file ${file/20/10}; done
  1. Remove quotes from the argument to in. Otherwise, the filename expansion does not occur.
  2. The $in the substitution should go beforethe bracket
  1. 从参数中删除引号到in. 否则,不会发生文件名扩展。
  2. $在替代应该去支架

回答by Hai Vu

Here is a solution which use the findcommand:

这是使用该find命令的解决方案:

find . -name '20*' | while read oldname; do echo mv "$oldname" "${oldname/20/10}"; done

This command does not actually do your bidding, it only prints out what should be done. Review the output and if you are happy, remove the echocommand and run it for real.

此命令实际上并不执行您的出价,它仅打印出应该执行的操作。查看输出,如果您满意,请删除该echo命令并真正运行它。

回答by Virgil Ming

Just wanna add to Explosion Pill's answer. On OS X though, you must say

只是想添加到爆炸丸的答案中。不过在 OS X 上,你必须说

mv "${file}" "${file_expression}"

Or the mvcommand does not recognize it.

或者mv命令无法识别它。

回答by Gilles Quenot

Brace expansions like :

支撑扩展如:

{*/20?????.*/20/10}

can't be surrounded by quotes.

不能被引号包围。

Instead, try doing (with Perl rename) :

相反,尝试做(使用 Perl rename):

rename 's/^10/^20/' */*.ext 

You can do this using the Perl tool renamefrom the shellprompt. (There are other tools with the same name which may or may not be able to do this, so be careful.)

您可以renameshell提示符下使用 Perl 工具执行此操作。(还有其他同名的工具可能会也可能不会这样做,所以要小心。)

If you want to do a dry run to make sure you don't clobber any files, add the -nswitch to the command.

如果要进行试运行以确保不会破坏任何文件,请将-n开关添加到命令中。

note

笔记

If you run the following command (linux)

如果您运行以下命令 ( linux)

$ file $(readlink -f $(type -p rename))

and you have a result like

你有这样的结果

.../rename: Perl script, ASCII text executable

then this seems to be the right tool =)

那么这似乎是正确的工具 =)

This seems to be the default renamecommand on Ubuntu.

这似乎是默认rename的命令Ubuntu

To make it the default on Debianand derivative like Ubuntu:

要使其成为默认值Debian和衍生物,例如Ubuntu

sudo update-alternatives --set rename /path/to/rename

回答by William Pursell

The glob behavior of *is suppressed in double quotes. Try:

的 glob 行为*在双引号中被抑制。尝试:

for file in */20?????.*; do
    echo "${file/20/10}";
done