使用 mv 移动到另一个目录并立即重命名

使用 mv 移动到另一个目录并立即重命名

我想知道每个+100Mb并且在上个月没有被访问过的文件,并且我已经成功写入:

find / -size +100M -atime +30

现在我想将这些文件移动到名为 /big-not-used 的文件夹,并将其名称更改为:file_nameYYYYMMDD其中 file_name 是原始文件的名称,YYYYMMDD 是今天的日期,以年月日为单位。例如film.mkv转到/big-not-used/film.mkv20161031

我的句子是:

find / -size +100M -atime +30 -exec mv {} /big-not-used/... \;

但我不知道如何在文件名中附加今天的日期。我发现date +%Y-%m-%d输出:2016-10-31这很有用。现在的疑问是如何获取这个文件的名称?下列的: https://stackoverflow.com/questions/5456120/how-to-only-get-file-name-with-linux-find

... -exec basename {} \;

或许?:

find / -size +100M -atime +30 -exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;

但它给出了一个错误,因为 basename 正在回复文件的完整路径而不是我将使用的名称:

${var##/*/}

获取文件名,但问题是如何将basename {}回复插入到前面表达式中的 var 中!?

或许?

$(${$(basename {})##/*/})

但它说在意外的“}”附近有语法错误...

答案1

您正在接近:

find / -size +100M -atime +30 \
  -exec mv {} /big-not-used/$(basename {})$(date +%Y-%m-%d) \;

$(...)但如果不加引号,就会发生结构的外壳扩展find在命令执行之前。换句话说,给定上面的命令行,实际执行的是:

find / -size +100M -atime +30 \
  -exec mv {} /big-not-used/{}2016-10-30 \;

因为 的结果$(basename {})只是{},这就是为什么你最终得到完整路径名。试试这个:

find / -size +100M -atime +30 \
  -exec sh -c 'mv {} /tmp/big-not-used/$(basename {})$(date +%Y-%m-%d)' \;

为了进行测试,您可以替换mvecho mv,如下所示:

find / -size +100M -atime +30 \
  -exec sh -c 'echo mv {} /tmp/big-not-used/$(basename {})$(date +%Y-%m-%d)' \;

...并查看生成的命令是什么样的。

答案2

我改进了lark的解决方案,只进行一次sh调用:

find / -size +100M -atime +30 -exec sh -c \
  'for f do mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"; done' sh {} +

或者,sh根本没有任何调用:

while IFS= read -r f; do
  mv "$f" /tmp/big-not-used/"$(basename "$f")$(date +%Y-%m-%d)"
done < <(find / -size +100M -atime +30)

(后者假设文件名中没有任何换行符。)

为了调试,您可能需要添加-vmv如果支持的话)。

相关内容