【问题标题】:Rename certain files recursively in a directory - Shell/Bash script递归重命名目录中的某些文件 - Shell/Bash 脚本
【发布时间】:2017-09-15 00:04:54
【问题描述】:

我到处搜索,想出下面这个脚本。我无法弄清楚这里的问题是什么。 我正在尝试遍历名为 Extracted_Source 的目录中的所有目录,以重命名任何带有附加时间戳的 CSV 文件。 任何帮助表示赞赏。

我一直收到一个

No such file or directory./Extracted_Source/*

以下是来源:

for files in ./Extracted_Source/*
do if ["$files" contains ".csv"]
then mv "$files" "${files%}_$(date "+%Y.%m.%d-%H.%M.%S").csv";
fi done; echo end

【问题讨论】:

  • 这意味着文件夹Extracted_Source 不存在于您当前的工作目录中,或者Extracted_Source/ 不包含任何文件。 ls ./Extracted_Source/* 显示什么?我想这将是同样的事情。
  • 您的参数扩展带子字符串删除 ${files%} 删除nothing。也许你打算${files%.csv}_...

标签: bash shell directory rename


【解决方案1】:

首先,错误消息意味着您在./Extracted_Source/ 中没有任何文件或文件夹。但是,以下方法将起作用:

#!/bin/bash

for file in ./Extracted_Source/*/*.csv; do
    mv "$file" "${file/.csv}_$(date "+%Y.%m.%d-%H.%M.%S").csv";
done

echo end

这不包括已移动的 csv 文件。

【讨论】:

  • 这不会重命名Extracted_Source 内的目录中的文件,这是问题的意图。
  • 谢谢@odradek - 我已经更新了我的答案,并删除了不必要的if 声明。
【解决方案2】:

我会使用find

find ./Extracted_Source -type f -name "*.csv" | while -r read files; do mv "$files" "${files%.*}_$(date "+%Y.%m.%d-%H.%M.%S").csv"; done

这还具有处理文件名中包含空格的文件的额外好处。

这是多行形式的相同内容:

find ./Extracted_Source -type f -name "*.csv" | \
while read -r files; do 
    mv "$files" "${files%.*}_$(date "+%Y.%m.%d-%H.%M.%S").csv"
done

您还可以使用进程替换来提供while 循环:

while read -r files; do 
    mv "$files" "${files%.*}_$(date "+%Y.%m.%d-%H.%M.%S").csv"
done < <(find ./Extracted_Source -type f -name "*.csv")

在您当前的脚本中,${files%} 没有做任何事情。文件的.csv 部分不会被删除。正确的方式是${files%.*}

自己试试看:for files in *; do echo "${files%.*}"; done

有关更多信息,请参阅Bash Hackers Wiki

【讨论】:

  • 你被 -name "*.csv" 覆盖了,但最好明确显示使用 substring removal 删除的内容,例如${files%.csv}_... 而不是 ${files%.*}_。你的做法没有错,这只是一个潜在的澄清。此外,由于它被标记为 bash,您可以使用 进程替换 来提供 while 循环,例如while read -r files; do ... done &lt; &lt;(find ./Extracted_Source -type f -name "*.csv")