我正在编写一个命令,将 x 个最旧的文件(FIFO)移动到一个目录中,将结果通过管道传输"find"
到目录中"ls"
还是仅使用“ ls
” ..请建议是否更好。
ls -ltr `/bin/find ${in}/* -prune -name "*.txt" -type f` | head -10 |
while read -r infile ; do
-move the file
done
或者我应该只使用ls.
我正在使用的原因是:我阅读了一些在脚本编写中应避免的find
在线内容。ls
但在我的代码最后,我必须将查找结果通过管道传输到ls
.我担心如果find
结果太大会导致任何问题。
答案1
尽管珀尔可能会比循环遍历大目录“x”次更快,这是一个蛮力简单的解决方案。
外循环确定将移动多少个文件——本例中为 3 个。在该循环中,我们将“最旧”的文件初始化为 globbing 产生的第一个文件名*
。然后,内部循环比较每个文件的时间戳以查看它是否早于 ( -ot
) 当前最旧的文件。如果是,我们将更新“最旧的”文件名。在内循环结束时,我们报告并移动该文件。
for((count=0; count < 3; count++))
do
set -- *
oldest=$1
for f in ./*
do
if [ "$f" -ot "$oldest" ]
then
oldest=$f
fi
done
echo mv -- "$oldest" ./.archive
mv -- "$oldest" ./.archive
done
答案2
Pythonheapq.nsmallest
重击:
find -printf '%T@ %p\n' |
python noldest.py 1000 |
xargs -Ixxx mv xxx directory_for_old_files
此find
命令以“自 1970 年起的秒数 (%T@)、空格、文件名 (%p)”格式列出文件。尾随xargs
命令从标准输入中一一获取文件名,并应用mv xxx directory_for_old_files
命令用它们替换 xxx。
noldest.py 实现可以是:
import sys
from heapq import nsmallest
from datetime import datetime
n = int(sys.argv[1])
date_file_pairs = (line.split(' ', maxsplit=1) for line in sys.stdin) # generators are lazy
def parse_date(date_and_filename):
seconds_from_1970 = float(date_and_filename[0])
return datetime.fromtimestamp(int(seconds_from_1970))
for _, filename in nsmallest(n, date_file_pairs, key=parse_date):
print(filename.rstrip('\n')) # lines in sys.stdin have trailing newlines
性能取决于nsmallest
Python标准库中算法的实现。