如何将除最后一个n
文件之外的所有文件从移动dir1
到dir2
?
我目前这样做,将时间设置为 的近似值n
,在我的例子中n=2
每 10 分钟一次。
find /dir1/ -name '*.txt*' -mmin +10 -type f -exec mv "{}" /dir2/ \;
类似的命令可以工作,但我不确定,有人可以确认应该如何调整吗?
ls -1tr | head -n -2 | xargs -d '\n' mv -f --
答案1
和zsh
:
mv dir1/**/*.txt*(D.om[3,-1]) dir2/
dir1
将除了 2 个最近修改的文件之外的常规文件移至dir2
.
**/
:任意级别的子目录。D
:包含隐藏文件并进入隐藏目录。.
:仅常规文件(无符号链接、目录...),相当于find
s-type f
。om
:按修改时间排序(最新的排在前面,如ls -t
)。[3,-1]
:仅从第三个到最后一个
(您可以发出 azmodload zsh/files
来获取内置函数mv
,或者zargs
如果您遇到arg 列表太大问题)。
POSIXly,如果不对文件名称、文件数量及其路径长度做出一些假设,就无法完成此操作。
GNUly(使用最新版本的 GNU 工具-z
),您可以这样做:
find dir1 -name '*.txt*' -type f -printf '%T@\t%p\0' |
sort -rnz | tail -zn +3 | cut -zf2- | xargs -r0 mv -t dir2
虽然 GNU sort
andxargs
已经有-z
/-0
选项数十年了,但添加-z
forcut
和tail
却是最近的事。如果您有旧版本,您可以随时执行以下操作:
find dir1 -type f -printf '%T@\t%p\0' | sort -rnz |
tr '\n\0' '\0\n' |
tail -n +3 | cut -f2- |
tr '\n\0' '\0\n' | xargs -r0 mv -t dir2
请注意,虽然这些解决方案在(包括子目录)中递归查找文件dir1
,但它们不会在dir2
.这意味着,例如,如果同时存在 adir1/file.txt
和dir1/subdir/file.txt
,它们最终都会被移动到dir2/file.txt
,一个覆盖另一个。
答案2
由于带日期戳的文件将按照 shell glob 的顺序收集在一起(例如*.txt
),因此您可以使用数组(例如在 bash 中):
n=2 ## how many of each you want to keep
txtfiles=(*.txt)
auxfiles=(*.txt_aux)
totaltxt=${#txtfiles[@]}
totalaux=${#auxfiles[@]}
movetxt=$((totaltxt-n))
moveaux=$((totalaux-n))
echo mv "${txtfiles[@]:0:movetxt}" /dir/aux2/
echo mv "${auxfiles[@]:0:moveaux}" /dir/aux2/
echo
当看起来效果正确时,将最后两块取下。
答案3
一种更简单的方法:
mv `ls -tr sourcedir | head -n -2` destdir
注意:这假设您知道目录中有两个以上的文件。如果你不确定,你可以用ls | wc -l