将最新文件从一个目录移动到另一个目录

将最新文件从一个目录移动到另一个目录

我正在尝试将最新文件从一个目录移动到另一个目录。该find命令找到文件,但不将它们移动到另一个目录。目标目录存在。

$ cd /app/path1/path2 && \
    find . -type f -printf "%C@ %p\n" | sort | tail -n 2 | \
    cut -d " " -f 2- |xargs -0 mv -t /app/path1/path2/path3

error:  mv: cannot stat No such file or directory

答案1

您的问题是由于您已经控制了 生成的输出的格式find,现在在换行符上拆分,\n。为了xargs在使用输出时处理您的输出,-0需要用空字符分隔\0。不过,这里有一个简单的方法来修复它:

$ find . -type f -printf "%C@ %p\n" | sort | tail -n 2 | \
    cut -d " " -f 2- | tr '\n' '\0' | xargs -0 mv -t /app/path1/path2/path3

引入 `tr '\n' '\0' 命令将新行转换回空值。

答案2

避免使用 xargs 的 -0 选项,或使用 -print0。 xargs 手册页的片段

在这些情况下,最好使用 -0 选项,这样可以防止出现此类问题。使用此选项时,您将需要确保为 xargs 生成输入的程序也使用空字符作为分隔符。例如,如果该程序是 GNU find,则-打印0选项会为您执行此操作。

答案3

如果您确定您的文件名不会包含换行符或不可打印的字符,那么这是极少数情况下,解析ls.

cd /app/path1/path2
latest_file=$(LC_ALL=C ls -cr | head -n 1)
mv "$latest_file" /app/path1/path2/path3

或者如果您想避免主 shell 进程中的目录更改:

latest_file=$(LC_ALL=C ls /app/path1/path2 -cr | head -n 1)
mv "/app/path1/path2/$latest_file" /app/path1/path2/path3

LC_ALL=C运行的设置ls可确保非 ASCII 字符在许多(但不是所有系统)上按字面打印;控制字符(不可打印)在许多系统上仍然被破坏。

您可以一次移动多个文件。为了仍然处理大多数文件名,请关闭通配符并设置IFS为仅在换行符处分割。

set -f; IFS='
'
mv $(ls -cr /app/path1/path2/* | head -n 2) /app/path1/path2/path3

如果您可以使用 zsh 作为 shell,这会容易得多,因为您可以使用全局限定符

mv /app/path1/path2/*(oc[1,2]) /app/path1/path2/path3

相关内容