我正在尝试将Documents
目录中的最后 8 个文件移动到另一个目录,但我不想将它们逐个移动到该特定目录。是否可以使用命令的替代来移动它们tail
,但针对的是目录而不是文件?我的意思是,我想使用类似tail -8 ./Documents | mv ./Anotherdirectory
或 之类的命令来执行此操作mv tail -8 ./Documents ./Anotherdirectory
。
事实上,我正在寻找一种巧妙的方法,可以ls
快速将最后 8 个文件(如所列)移动到另一个目录(无需输入每个名称)。有什么建议吗?
答案1
您可以使用for
,它以有序的方式循环遍历文件,并允许我们避免解析find
或的输出ls
,以避免文件名中出现空格和其他特殊字符的问题。非常感谢 @muru 对此的改进 :)
i=0; j=$(stat ~/Documents/* --printf "%i\n" | wc -l); for k in ~/Documents/*; do if (( (j - ++i) < 8 )); then echo mv -v "$k" ~/AnotherDirectory; fi; done
首先用 进行测试echo
,然后删除echo
以实际移动文件。
作为脚本:
#!/bin/bash
i=0
j=$(stat ~/Documents/* --printf "%i\n" | wc -l )
for k in ~/Documents/*; do
if (( (j - ++i) < 8 )); then
echo mv -v -- "$k" ~/AnotherDirectory
fi
done
再次,echo
测试后删除以真正移动文件
解释
i=0
告诉 shell 从 0 开始迭代j=$(stat ~/Documents/* --printf "%i\n" | wc -l )
这会将变量设置j
为一个整数,等于目录中文件总数。感谢Serg 回答了我的问题:如何可靠地计算文件数量,无论文件名称包含什么字符do if (( (j - ++i) < 8 ))
j
对于循环的每次迭代,测试减去循环运行次数的结果是否小于 8,如果是,则mv -v -- "$k" ~/AnotherDirectory
将文件移动到新目录
答案2
您可以使用命令替换来执行此类操作。在 Bash 中:
mv $(ls -d [sort options] source/* | tail -n8) destination
将$(command)
运行其中包含的任何内容,并将文本输出替换到外部命令中。该ls
命令将打印源目录中每个文件的路径,并根据您指定的标志进行排序,每行一个,因此tail
可以只取最后几个。因此,上面的命令将扩展为
mv source/file1 source/file2 source/file3 ... source/file8 destination
您可以直接运行ls -d [sort options] source/* | tail -n8
来查看它将复制哪些文件。
根据您对输出ls
和文件命名的排序方式,您可能能够更简单地完成您要查找的操作,只需使用某种变体mv source/name_* destination
将以“name_”开头的所有内容复制到目标目录即可。
编辑: 当文件名中有空格时,上述代码会中断。解决这个问题的一个更复杂的替代方案是
ls -d1 [sort options] source/* | tail -n8 | tr '\n' '\0' | xargs --null mv -t destination
尽管它仍然利用解析ls
输出来按非字母顺序进行排序。
答案3
与 t-mager 的建议类似,您可以使用 ls 排序选项并将最后 8 个文件放入列表中,这些就是您的文件:
1 10 2 3 4 5 6 7 8 9
使用以下命令:
for n in `ls|tail -8`; do mv $n ~/temp; done
答案4
我发现这也有效:
ls -1 [sort options] | tail -n2 | xargs -I {} -n 1 echo "mv \"{}\" ../t2/"
当然,必须消除回声:
ls -1 | tail -n2 | xargs -I {} -n 1 mv "{}" ../t2/
可以"{}"
替换为'{}'
实际上,作为最后的实验,删除(双)引号也是可行的。令人惊讶的是,但经过测试。