我正在尝试将最新文件从一个目录移动到另一个目录。该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