重命名/移动(mv)以特定名称开头的多个文件

4
我将尝试重命名一个目录中符合特定模式的多个文件。
文件列表:
stack_overflow_one.xml
stack_overflow_two.xml
stack_overflow_one.html

我想将stack_overflow重命名为heap_graph
heap_graph_one.xml
heap_graph_two.xml
heap_graph_one.html

我尝试了以下内容:
使用rename命令:
rename stack_overflow heap_graph stack_overflow* # returns 'The syntax of the command is incorrect.'

使用Bash中的for循环。
# how can I write this in one line? I've tried wrapping in one line, but also does not work
for i in stack_overflow* do
    mv "$i" "${i/stack_overflow/heap_graph}"
done

然而,这些都没有起作用。

1
有许多不同的rename实现在各处流传,支持不同的语法 - 在我的电脑上,语法是rename s/stack_overflow/heap_graph/ stack_overflow* - gboffi
1
在for循环中使用分号将其写在一行上:for foo in bar; do something; done - Olli K
如果您发现任何给出的答案有用,请查看当有人回答我的问题时我该怎么办?什么是“已接受的答案”? - Inian
2个回答

1
你所遇到的问题是在 for 循环中出现了一个微不足道的语法错误。你的脚本其余部分应该可以正常工作,没有任何问题。
for i in stack_overflow*; do
#                      ^^^ missing semi-colon
# The below condition to handle graceful loop termination when no files are found
    [ -f "$i" ] || continue
    mv "$i" "${i/stack_overflow/heap_graph}"
done

ghoti所述,如果你在Bourne Again Shell bash而不是POSIX Bourne Shell(sh)中,上面的解决方案是可移植的,你可以使用特殊的globbing选项来避免处理没有文件返回时的情况。

shopt -s nullglob
for i in stack_overflow*; do
    mv "$i" "${i/stack_overflow/heap_graph}"
done

shopt -u nullglob

-s选项设置它,-u选项取消它。更多关于shopt内置命令的信息,请参阅GNU bash页面


0

半常用的实用工具mmv(article)对于你所描述的“多次移动”情况非常有用。

$ mmv -n 'stack_overflow_*' 'heap_graph__#' # remove -n after testing
mv -- stack_overflow_one.html heap_graph_one.html
mv -- stack_overflow_one.xml heap_graph_one.xml
mv -- stack_overflow_two.xml heap_graph_two.xml

正如您所看到的,它只是针对匹配的模式多次调用mv

*是类似于Bash使用的通配符,但它被引号转义以传递给mmv_#是对匹配的引用,也被转义(尽管文档建议改用#1)。

这一系列命令还可用于复制(cp)和链接(ln)。


如果你恰好有Zsh(一种常见的Bash升级/替代品),你已经拥有zmv,它可以类似地使用以下命令完成任务:
% zmv -n 'stack_overflow_(*)' 'heap_graph_$1'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接