ls -t | head -n1 不错,但要小心;如果子目录是最近修改的,它将占用第一个插槽,不仅会导致尝试将该目录移动到自身中(不允许,这可能是您的问题“第二行中的路径”),但可能会删除其余文件,包括您要保留的文件。有很多方法可以过滤掉任何目录;在我的脑海中,你可以ls -tp | grep -v '/$' | head -n1。请注意,将文件添加到目录会影响 posix 上的目录 mtime(上次修改时间)。
删除所有文件很容易,一旦您将要保留的文件移出,只需rm *。请注意,这不会删除目录(只要您不放 -r),我认为这是您想要的,因为您似乎正在将要保留的文件移动到它所在的子目录。
您可能还想添加一些错误捕获,因此如果某个步骤失败,以后的步骤不要删除您不想删除的文件。我不使用自动机,但只要您使用真正的 bash,这应该可以工作:(包括其他调度程序,如 cron,只要您首先进入正确的工作目录)
mv -- "$(ls -tp | grep -v '/$' | head -n1)" subdirectory/ && rm *
&& 意味着只有在前面的事情成功时才做后面的事情。将./ 添加到目标文件的开头没有任何作用,但在末尾保留/ 可以防止创建一个名为“子目录”的新文件(如果它不存在)。另外,我很确定您发送的代码 sn-p 中的“”是将其标记为与您的实际代码不同,但以防万一:请注意,无论调用什么子目录,都可能需要特殊处理如果它确实包含这些字符。
编辑:
我刚刚在问题中注意到约束“获取超过 30 天的文件夹中的过滤文件列表”。所以,稍作改动:(用find比较时间)
mv -- "$(find -maxdepth 1 -type f -mtime +30 -printf '%T@ %f\n' | sort -rn | head -n1 | cut -d\ -f2-)" subdirectory/ && find -maxdepth 1 -type f -mtime +30 -delete
解释:在当前目录(不是子目录,所以 maxdepth 1)中查找 mtime 至少为过去 30 天(-mtime +30)的文件(不是目录,类型 f)并打印修改和名称 (%T@ %f);像倒序(-r)中的数字(-n)一样排序;只取第一个(head -n1);提取文件名(第二个+空格分隔的字段)并将其移动到子目录。如果成功,请删除任何符合与以前相同的查找条件的内容。
我不会将文件放在环境变量中,除非磁盘 /very/ 很慢且未缓存。过滤掉你移动的文件名所花费的时间可能比重新查询磁盘要花费更多的精力,除非你有大量的文件,在这种情况下它们可能不适合环境部分。
编辑 2: KamilCuk 是对的。使用 null 终止,因为 null 是文件名中不允许的(唯一字符):
find -maxdepth 1 -type f -mtime +30 -printf '%T %f\0' | sort -z -t' ' -r -n -s -k1 | head -z -n1 | cut -z -d' ' -f2- | xargs -0 -I{} mv {} subdirectory/ && find -maxdepth 1 -type f -mtime +30 -delete