我想知道每个+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)' \;
为了进行测试,您可以替换mv
为echo 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)
(后者假设文件名中没有任何换行符。)
为了调试,您可能需要添加-v
(mv
如果支持的话)。