是否有类似 mv 但带有正则表达式的 Linux 命令?

是否有类似 mv 但带有正则表达式的 Linux 命令?

例如我mv (.*?).sql $1.php想要

是否有一个命令可以让我指定重命名模式?

答案1

正如其他人提到的,rename这很好,但man rename在尝试之前请阅读手册页()。至少有两种完全不同的工具rename,您使用哪种工具取决于您的发行版。错误地调用它们可能会很危险。

这是手册页Larry Wall 编写的基于 perl 的版本随 Ubuntu 一起提供。您可以给它一个 perl 表达式,例如rename 's/\.sql$/.php/' *.sql

这是手册页用于旧版 Red Hat 和 CentOS 发行版附带的重命名。用法是简单的字符串替换,例如rename .sql .php *.sql

您还可以使用 bash 单行命令一次处理一个文件:

$ for f in *.sql; do mv -i "$f" "${f%%.*}.php"; done

答案2

rename(1),它不使用正则表达式,但可以解决您的问题:

rename .sql .php *.sql

还有mmv(1),但我不熟悉它是如何工作的。

答案3

您也可以尝试输入

for i in $(\ls -d *.sql)
do
mv $i $(echo $i | sed -e 's/\.sql$/\.php/')
done

或者让它使用正则表达式,稍微改变一下

for i in $(\ls -d | egrep -e '.*\.sql')
do
mv $i $(echo $i | sed -e 's/\.sql$/\.php/')
done

获得一些 shell 编码的乐趣。

答案4

作为一名水管工,我喜欢管道:)

注意:这个答案很冗长 - 作为新手,我很感激知道的人花时间解释,所以我会“转发”。如果你不是新手,请原谅我的冗长和冗长。

ls -1 *_201[67][0-9]* | sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/' | bash

在哪里:

ls -1 *_201[67][0-9]*

列出与模式匹配的所有文件,在本例中,我正在寻找文件名中日期格式为“YYYYMMDD”的文件

sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/'
#        : | |    |     |                  | |       |                    |:                                 :
#        : |^2....^    ^3..................^^4.......^                    |:                                 :
#        :^1..............................................................^:                                 :
#        /................filename.................pattern................./...mkdir...and....mv...command.../

^1:第一个捕获组 - 整个文件名

^2:第二个捕获组 - 文件名模式的第一部分

^3:第三个捕获组 - 第二个文件名部分 - 此处的日期为“YYYYMMDD”

^4:第四个捕获组 - 日期和扩展名之间的可选文件名部分,以及扩展名本身

那么......如果我有一个名为的文件

CallLog_555123412_20161231-214403.7z

...然后

mkdir -p \2\/\3; mv \1 \2\/\3\/\1

实际上意味着

# make directory and sub-directory
mkdir -p CallLog_555123412/20161231
# move file from current directory to sub-sub-directory just created
mv CallLog_555123412_20161231-214403.7z CallLog_555123412/20161231/CallLog_555123412_20161231-214403.7z

请注意,sed 命令的输出通过管道传输到“bash”以执行它。为了首先看到建议的文件移动而不实际移动它们,首先删除末尾的“| bash”,然后尝试如下操作:

ls -1 *_201[67][0-9]* | sed -e 's/\(\(.\+\)[-_]\(201[67][0-9]\{4\}\)\([^.]\+\)\?\.[0-9a-z]\{2,3\}\)/mkdir -p \2\/\3; mv \1 \2\/\3\/\1/'

这不会做出任何改变,但是如果您在末尾加上“| bash”标签来运行它,您将看到将执行的命令。

这很有用,因为您可以从文件名的部分或添加到 sed 命令中的“替换”文本的任何其他内容创建所需的任何子目录。但请注意,sed 需要大量转义字符。

SED 正则表达式括号:

(...)需要转义以进行捕获分组 --> \(...\)

{m,n} 需要转义以量化前一个对象 --> \{m,n\}

/ 需要在替换字符串中转义 --> \/

[...] 不需要对字符类进行转义

替换字符串中的 \1 指的是第一个捕获组,依此类推......

安全警告:除非您完全了解结果,否则切勿向“bash”发送任何东西...

希望这有助于清除一些障碍:)

相关内容