【问题标题】:Rename only unique files仅重命名唯一文件
【发布时间】:2020-04-11 03:16:36
【问题描述】:

如何通过从文件名中删除“1”来仅重命名唯一文件并保留重复的名称文件?

输入:

-english_1.pdf  
-english_2.pdf  
-english_3.pdf  
-mathematics_1.pdf  
-theology_1.pdf  
-economics_1.pdf  
-economics_2.pdf

如何使用 或类似名称从 math_1.pdf 和 theology_1.pdf 中删除 1

期望的输出

-english_1.pdf  
-english_2.pdf  
-english_3.pdf  
-mathematics.pdf  
-theology.pdf  
-economics_1.pdf  
-economics_2.pdf

我试过了:

rename -n  's/1//' *.pdf

但它会删除 所有 1

【问题讨论】:

  • 操作(创建/销毁/移动)文件和进程的工具是shell,而不是awk。为什么要涉及awk? edit 您的问题是用您使用的任何外壳(或非 UNIX 环境)标记它,以便我们为您提供帮助。包括具有1s 的文件名,如果存在,您不想删除并显示预期的输出(不清楚您是否也希望删除_s,实际上我什至不确定您提供的内容是否是样本输入或预期输出!)。
  • rename的问题在于thisthis有两个版本。你有哪个版本?如果您有 perl-ish 重命名,我认为您非常接近 rename -n 's/_1$//' *.pdf
  • 它似乎比 sed 和重命名更通用,我不知道
  • 当然是,但它是一种用于操作文本的工具,而不是操作文件(或进程)——这就是 shell 的用途。您极不可能需要像 sed 或 awk 这样的外部工具来为这样的工作生成文件名。有关如何获得帮助,请参阅我的第一条评论。
  • @KamilCuk 失败!重命名 V 是第一个

标签: awk sed shell sh rename


【解决方案1】:

安全的赌注可能是以下方法:

for file in *_1.pdf; do
   [ -f "${file/_1.pdf/_2.pdf}" ] || mv "${file}" "${file/_1.pdf/.pdf}"
done

它的作用如下:

  • for file in *_1.pdf; do ... done: 对匹配 glob 模式 *_1.pdf 的所有文件进行循环。所以这匹配所有看起来像prefix_1.pdf的文件
  • [ -f "${file/_1.pdf/_2.pdf}" ]: 我们在循环中做的第一件事是验证是否存在名称为prefix_2.pdf 的类似文件。我们通过参数扩展获得这个文件名

    ${parameter/pattern/string}: 模式替换。 pattern 被扩展以产生一个模式,就像在路径名扩展中一样,参数被扩展并且pattern 与其值的最长匹配被替换为string

    来源:man bash

    test 命令写成[ -f filename ] 检查是否存在带有filename 的文件。请参阅man test 了解更多信息。

  • 如果上述测试成功,我们什么也不做。如果上述测试不成功,我们将原文件重命名为mv "${file}" "${file/_1.pdf/.pdf}"。这种条件组合是使用 on OR-list 实现的:

    OR 列表的格式为 command1 || command2。当且仅当command1 返回非零退出状态时,command2 才会执行。

    来源:man bash

我在这里假设如果 prefix_3.pdf 存在,则文件 prefix_2.pdf 必须存在。

您可以通过在mv 命令前添加echo 来验证上述内容。

【讨论】:

  • 你能详细解释一下 [ -f "${file/_1.pdf/_2.pdf}" ] 的 "/" 和 | 的含义吗? |
  • @KarimBnAbdlaziz 我已经用所有需要的信息扩展了答案。
猜你喜欢
  • 2018-08-17
  • 2022-01-19
  • 1970-01-01
  • 2017-12-25
  • 1970-01-01
  • 2020-01-11
  • 2012-03-05
  • 2011-01-05
  • 2021-04-06
相关资源
最近更新 更多