将名称中带有空格的文件移动到以文件修改日期命名的文件夹中

Move files with whitespaces in their names to folders named like the files' modification dates

我根据修改日期创建了一堆文件夹,如下所示: .. 2012-11-29 2012-11-20 ..

现在我想将文件移动到这些文件夹中,以防修改日期与文件夹名称相同。这些文件的名称中包含空格。

如果我 运行 这样做,我会得到一个类似于文件夹名称的列表:

find . -iname "*.pdf" -print0 | while read -d $'[=10=]' file; do stat -c "%.10y" "$file"; done

如何获取此输出并在移动这些文件的脚本中使用它(伪代码):

find . -iname "*.pdf" -print0 | while read -d $'[=11=]' file; do mv $<FILEWITHWHITESPACEINNAME> <FOLDERNAMEDLIKE $file stat -c "%.10y" "$file" > ; done
find . -iname "*.pdf" -print0 |
  while IFS= read -r -d '' file; do
    folder=$(stat -c "%.10y" -- "$file") || continue  # store date in variable
    [[ $file = ./$folder/$file ]] && continue         # skip if already there
    mkdir -p -- "$folder" || continue                 # ensure directory exists
    mv -- "$file" "$folder/"                          # actually do the move
  done
  • 要正确读取 NUL-delimited 名称,请使用 IFS= 以避免丢失前导或尾随空格,并使用 -r 避免丢失文件名中的反斜杠。参见 BashFAQ #1
  • 在您的 shell 循环中,您有 shell 个变量——因此您可以使用其中一个变量来存储 stat 命令的输出。参见 How do I set a variable to the output of a command in bash?
  • 使用 -- 表示 end-of-arguments,因此即使您的 find 被替换为可以发出以 - 而非 [=17] 开头的路径的内容=],我们不会尝试将 file 中的值视为位置参数(文件名,在 statmkdirmv 的上下文中)。
  • 在循环中使用 || continue 意味着如果任何步骤失败,我们不会执行后续步骤——所以如果 [=13] 我们不会尝试执行 mkdir =] 失败,如果 mkdir 失败,我们不会尝试执行 mv