Automator - 在过滤列表中查找并移动最新文件
Automator - find and move most recent file in filtered list
我正在尝试使用 Automator
- 获取文件夹中超过 30 天的文件过滤列表(确定)
- 将最近的那些(如果有的话)移动到现有的子文件夹
- 垃圾其他人。
第 1 步很简单,但我无法找到执行第 2 步的方法 -- select 并移动最新的筛选集。
结果将是:如果工作流每月安排一次,则子文件夹每月将包含一个文件,而父文件夹将仅包含 31 天以内的文件
有办法吗?
更新
我尝试将 shell 脚本添加到自动化工作流程
fn=$(ls -t | head -n1)
mv -f -- "$fn" ./<subdirectory>/
但是第二行的路径有问题。
ls -t | head -n1
很好,但要小心;如果子目录是最近修改的,它将占用第一个位置,不仅会导致尝试将该目录移动到自身(不允许,这可能是您的问题"with the path in the second line"),而且可能会删除其余部分的文件,包括您要保留的文件。有很多方法可以过滤掉任何目录;在我的脑海中,你可以 ls -tp | grep -v '/$' | head -n1
。请注意,将文件添加到目录会影响 posix.
上的目录 mtime(上次修改时间)
删除所有文件很容易,一旦您移出要保留的文件,只需 rm *
。请注意,这不会删除目录(只要您不放 -r),我认为这是您想要的,因为看起来您正在将要保留的文件移动到它所在位置的子目录中。
您可能还想添加一些错误捕获,这样如果某个步骤失败,后续步骤不会删除您不想删除的文件。我不使用 automator,但只要你使用真正的 bash,这应该可以工作:(包括其他调度程序,如 cron,只要你首先进入正确的工作目录)
mv -- "$(ls -tp | grep -v '/$' | head -n1)" subdirectory/ && rm *
&& 意思是先行成功后才做后续。将 ./
添加到目标文件的开头没有任何作用,但将 /
保留在末尾可以防止创建名为 "subdirectory" 的新文件(如果该文件尚不存在)。另外,我很确定您发送的代码片段中的“<>”是为了将其标记为与您的实际代码不同,但以防万一:请注意,无论调用什么子目录,如果它可能需要特殊处理实际上确实包含这些字符。
编辑:
我刚刚注意到问题中的约束 "get a filtered list of files in a folder that are more than 30 days old"。所以,稍微改变一下:(使用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);将它作为一个数字 (-n) 以相反的顺序 (-r) 进行排序;只取第一个(head -n1);提取文件名(second+ space-delimited field)并将其移动到子目录。如果成功,请删除符合与之前相同的查找条件的任何内容。
除非磁盘/非常/慢且未缓存,否则我不会将文件放在环境变量中。过滤掉您移动的文件名所花费的时间可能比重新查询磁盘花费更多的精力,除非您有大量文件,在这种情况下它们可能不适合环境部分。
编辑 2: KamilCuk 是对的。使用 null 终止,因为 null 是文件名中不允许的(唯一字符):
find -maxdepth 1 -type f -mtime +30 -printf '%T %f[=12=]' | 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
我正在尝试使用 Automator
- 获取文件夹中超过 30 天的文件过滤列表(确定)
- 将最近的那些(如果有的话)移动到现有的子文件夹
- 垃圾其他人。
第 1 步很简单,但我无法找到执行第 2 步的方法 -- select 并移动最新的筛选集。
结果将是:如果工作流每月安排一次,则子文件夹每月将包含一个文件,而父文件夹将仅包含 31 天以内的文件
有办法吗?
更新 我尝试将 shell 脚本添加到自动化工作流程
fn=$(ls -t | head -n1)
mv -f -- "$fn" ./<subdirectory>/
但是第二行的路径有问题。
ls -t | head -n1
很好,但要小心;如果子目录是最近修改的,它将占用第一个位置,不仅会导致尝试将该目录移动到自身(不允许,这可能是您的问题"with the path in the second line"),而且可能会删除其余部分的文件,包括您要保留的文件。有很多方法可以过滤掉任何目录;在我的脑海中,你可以 ls -tp | grep -v '/$' | head -n1
。请注意,将文件添加到目录会影响 posix.
删除所有文件很容易,一旦您移出要保留的文件,只需 rm *
。请注意,这不会删除目录(只要您不放 -r),我认为这是您想要的,因为看起来您正在将要保留的文件移动到它所在位置的子目录中。
您可能还想添加一些错误捕获,这样如果某个步骤失败,后续步骤不会删除您不想删除的文件。我不使用 automator,但只要你使用真正的 bash,这应该可以工作:(包括其他调度程序,如 cron,只要你首先进入正确的工作目录)
mv -- "$(ls -tp | grep -v '/$' | head -n1)" subdirectory/ && rm *
&& 意思是先行成功后才做后续。将 ./
添加到目标文件的开头没有任何作用,但将 /
保留在末尾可以防止创建名为 "subdirectory" 的新文件(如果该文件尚不存在)。另外,我很确定您发送的代码片段中的“<>”是为了将其标记为与您的实际代码不同,但以防万一:请注意,无论调用什么子目录,如果它可能需要特殊处理实际上确实包含这些字符。
编辑:
我刚刚注意到问题中的约束 "get a filtered list of files in a folder that are more than 30 days old"。所以,稍微改变一下:(使用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);将它作为一个数字 (-n) 以相反的顺序 (-r) 进行排序;只取第一个(head -n1);提取文件名(second+ space-delimited field)并将其移动到子目录。如果成功,请删除符合与之前相同的查找条件的任何内容。
除非磁盘/非常/慢且未缓存,否则我不会将文件放在环境变量中。过滤掉您移动的文件名所花费的时间可能比重新查询磁盘花费更多的精力,除非您有大量文件,在这种情况下它们可能不适合环境部分。
编辑 2: KamilCuk 是对的。使用 null 终止,因为 null 是文件名中不允许的(唯一字符):
find -maxdepth 1 -type f -mtime +30 -printf '%T %f[=12=]' | 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