【问题标题】:Trying to rename .JPG to .jpg in shell CLI [closed]尝试在 shell CLI 中将 .JPG 重命名为 .jpg [关闭]
【发布时间】:2014-06-11 07:42:34
【问题描述】:

我正在尝试将目录中的所有文件从 .JPG ext 重命名为 .jpg,但它不起作用。

我浏览了网络并找到了一些东西,但我似乎无法工作。我尝试的最新一个是:

rename -n .JPG .jpg *.JPG

我使用-n 标志查看将要修改的内容,但没有得到响应(没有文件)。

我在这里做错了什么!?

【问题讨论】:

  • rename 是一个 perl 程序,默认不会安装。对于这类事情,我通常会结合使用 find、mv、echo 和 sed。
  • 尝试重命名 -n JPG jpg *.JPG 或重命名 's/\.JPG$/.jpg/' *.JPG
  • @JohnBarça Semitrue,rename 实际上有两种实现方式,并非所有系统都提供更有用的perl 版本。
  • @AdrianFrühwirth。感谢您的澄清。我害怕 perl,虽然当我看到我写的 linux one liners 来消除这种恐惧时,也许我不应该是 :D

标签: linux shell rename command-line-interface batch-rename


【解决方案1】:

如果你不想使用重命名,你提到你已经尝试了各种方法,那么只使用内置的 bash 工具,你就可以做到这一点。

for x in `find . -maxdepth 1 -type f -name "*.JPG"` ; do mv "$x" `echo $x|sed 's/JPG/jpg/g'`; done

find 周围的反引号运行表达式并将结果分配给变量 x。例如,如果您需要比当前目录中的所有 JPG 更复杂的搜索,则可以使用各种开关与 find 一起限制时间、大小等。 Maxdepth 1 将搜索限制在当前目录。

编辑:

正如 Adrian 所指出的,使用 sed 是不必要且浪费的,因为它使用了另一个子 shell,因此可以将其全部压缩为:

 for x in `find . -maxdepth 1 -type f -name "*.JPG"` ; do mv "$x" "${x%.JPG}.jpg"; done

【讨论】:

  • 正如我在对我的回答的评论中所说,for foo in $(find) should be avoidedsedconstruct 也不需要(例如,您可以使用 mv "$x" "${x%.JPG}.jpg" 避免两个子外壳(更快)并且更短。此外,不要忘记引用您的变量,否则它们将受到通配符和分词的影响,这意味着某些文件名将完全破坏您的命令。
  • @AdrianFrühwirth。好的,因为我喜欢它的灵活性,所以留在 find 中,但进行了您建议的其余编辑。再次感谢。
【解决方案2】:

正确的perl rename 需要一个正则表达式,所以你可以做到这一点:

$ rename 's#\.JPG$#.jpg#' *.JPG

糟糕的util-linux 版本的rename 没有-n 开关,所以你必须这样做:

$ rename .JPG .jpg *.JPG

请查阅man 页面以检查您的系统上实际安装了哪个实现。

【讨论】:

  • 有趣的是,在大小、时间、深度等可用开关方面,您认为 rename 与使用 find 方法相比如何?
  • @JohnBarça rename 没有递归模式,这可能是最重要的场景,它本身并没有那么有用(但鉴于整个脚本只是几个 LOC,我猜一个可以很容易地添加这个)。当然,如果您需要以某种方式限制结果,find 绝对是正确的工具,但不要 这样做for f in $(find ...)(请参阅here 原因)。再说一次,没有什么能阻止你将两者结合起来。
猜你喜欢
  • 1970-01-01
  • 2017-09-30
  • 1970-01-01
  • 2013-02-02
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
  • 2018-09-10
  • 2013-12-26
相关资源
最近更新 更多