【问题标题】:How to exclude new lines (carriage returns) using find regex on GNU/Linux cli?如何在 GNU/Linux cli 上使用 find regex 排除新行(回车)?
【发布时间】:2019-03-25 11:37:30
【问题描述】:

我正在尝试将具有 de JPG 扩展名的目录中的所有文件重命名为小写 jpg。 我在this post 的帮助下编写了这个 bash 代码:

find . -regex ".*\.JPG" -exec sh -c 'echo "$0" | sed -r "s/\.JPG/\.jpg/" && mv "$0" "$1"' {} \;

但我收到以下错误:

./IMG_1352.jpg
mv: cannot move './IMG_1352.JPG' to '': No such file or directory
(and so on...)

我想我需要更改名称“地点”,但我不知道如何。

【问题讨论】:

  • 你是在暗示你有\r的吗?在你的文件名中?
  • 正如您在我的帖子中看到的,$1 变量是空的。 $0 获取找到的文件 {} 的值,但是没有 $1 参数。

标签: linux bash rename


【解决方案1】:

TL;DR:试试这个代码:

find . -name '*.JPG' -type f -exec sh -c 'mv $0  ${0/.JPG/.jpg}' {}  \;

更多评论:

您的代码非常接近它需要的位置。但是,有一个问题是没有定义 $1。

我运行了以下代码来确定 $1 的价值。

$ ls
bye.jpg hi.JPG
$ find . -regex ".*\.JPG" -exec sh -c 'echo "$0" | sed  "s/\.JPG/\.jpg/" && echo "0:$0 1:$1" ' {} \;
./hi.jpg
0:./hi.JPG 1:

根据我上面的结果,$1 中没有 值。您应该知道 $1 实际上是指传递给 sh 的第二个参数。即 sh -c 'code' $0 $1 ...

无论如何,您需要在变量中捕获 sed 命令的结果,然后将其传递给 move 命令,如下所示:

find . -regex ".*\.JPG" -exec sh -c '
    lower=$( echo "$0" | sed -r "s/\.JPG/\.jpg/" )
    mv "$0" "$lower"
' {}  \;

说了这么多,你可以让它更简洁。正如 PS 所暗示的,for 循环是一个不错的选择。此外,根据 PS 的建议,JPG -> jpb 替换更具可读性。如果你对使用 find 很感兴趣,你可以合并 PS 的建议如下:

find . -regex ".*\.JPG" -exec sh -c '
    filename=$0
    mv "$filename" "${filename/.JPG/.jpg}"
' {}  \;

【讨论】:

  • 谢谢你,马克,你的解决方案很有效!但我有一个问题:在${0/.JPG/.jpg}' 中必须使用括号还是可以使用'$(0/.JPG/.jpg)'`?
  • @Damon - ${0/.JPG/.jpg} 是要走的路 - $() 语法,即带括号,告诉 shell 执行命令 - AFAIK $()相当于``.
猜你喜欢
  • 2019-12-24
  • 2012-05-04
  • 2020-04-15
  • 2015-06-26
  • 2018-03-28
  • 2015-03-20
  • 2021-12-04
  • 2023-02-08
  • 2018-02-02
相关资源
最近更新 更多