我想要做的是,监视一个目录(不是递归的,只是一个)是否创建了新文件,并将这些文件在写入时附加到一个大文件中。
正在写入的文件数量巨大,可能达到 50,000 个之多。
通过使用inotifywait
,我正在监视目录,例如:
inotifywait -m -e create ~/folder | awk '($2=="CREATE"){print $3}' > ~/output.file
所以我存储创建的新文件的名称~/output.file
,然后使用 for 循环
for FILE in `cat ~/output.file`
do
cat $FILE >> ~/test.out
done
如果写入(创建)文件的速率~/folder
类似于每秒 1 个文件,那么它工作得很好。
但要求很大,并且创建文件的速率非常高,比如每分钟 500 个文件(甚至更多)。
我检查了进程完成后的文件数量~/folder
,但与输出不匹配inotifywait
。存在大约 10-15 个文件的差异,具体情况因人而异。
另外,循环
for FILE in `cat ~/output.file`
do
done
~/output.file
不会在写入时处理所有文件。
谁能建议我一个优雅的解决方案来解决这个问题?
答案1
无需对输出进行后处理...使用inotifywait
选项--format
,--outfile
如果我运行:
inotifywait -m --format '%f' -e create /home/don/folder/ --outfile /home/don/output.file
然后打开另一个选项卡cd
并~/folder
运行:
time seq -w 00001 50000 | parallel touch {}
real 1m44.841s
user 3m22.042s
sys 1m34.001s
(所以我每分钟收到超过 500 个文件)一切正常并且output.file
包含50000
我刚刚创建的所有文件名。
一旦该过程完成将文件写入磁盘,您就可以将其内容附加到您的文件中test.out
(假设您始终处于~/folder
):
xargs < /home/don/output.file cat >> test.out
或者,read
如果您想在文件创建时对其进行处理,请使用。所以,尽管你~/folder
可以运行:
inotifywait -m --format '%f' -e create ~/folder | while read file; do cat -- "$file" >> ~/test.out; done
答案2
您可以做的一件事是制作一个小程序,在处理后将已处理的文件从目录移至另一个目录。完成后只需重新启动目录扫描即可。如果没有文件,则在重新扫描之前休眠一段合理的时间,并在生成文件期间执行此操作(生成文件的进程似乎仅运行最多 100 分钟左右)。
如果无法从目录中移动文件,另一种方法是从过去某个位置的日期时间戳 DTS 开始。然后找到所有比 DTS 新的文件,处理它们,如果文件的时间戳比 DTS 新,则更新 DTS 。与上述解决方案一样重复此过程。如果时间戳的粒度阻止两个文件具有相同的文件,则您可以只查找比 DTS 更新的文件。如果不是,您必须查找不早于 DTS 的文件,并保留您将在下次运行时使用的 DTS 的文件列表,并在下次运行时过滤掉这些文件。