awk中是否有任何内置的防止写入这样awk的另一个实例已写入同一文件支持?
考虑以下:
$ # Create large input file
$ for i in {1..500000}; do echo "$i,$i,$i" >> /tmp/LargeFile.txt; done
$ # Launch two simultaneous instances of awk outputting to the same file
$ awk -F"," '{print $0}' /tmp/LargeFile.txt >> /tmp/OutputFile.txt & awk -F"," '{print $0}' /tmp/LargeFile.txt >> /tmp/OutputFile.txt &
$ # Find out how many fields are in each line (ideally 3)
$ awk -F"," '{print NF}' /tmp/Output.txt | sort | uniq -c
1 0
553 1
1282 2
996412 3
1114 4
638 5
因此,两个AWK实例大量数据的同时输出到相同的文件中。理想地,输出文件将具有每行3逗号分开的值,但由于两个实例在同一时间写入到相同的文件,某些行可以具有多于3逗号分隔值,并且一些将有少于3。
例如损坏的输出文件:
1,1,1 < 1's from from first instance of awk
2,2,2 < 2's from from first instance of awk
3,3,3 < 3's from from first instance of awk
1,1,1 < 1's from from second instance of awk
2,2,2 < 2's from from second instance of awk
4,4,4 < 4's from from first instance of awk
5,5,5 < 5's from from first instance of awk
3,3,3 < 3's from from second instance of awk
4,6,6,4,6 < corrupted input as both instances tried to write to this line at the same time
4
7,7,7 < 7's from from first instance of awk
有什么好看的,简单的方法来防止这种情况?
通过AWK的每个实例进行的处理会更是这样的:从其它进程的数据被连续地写入的文件,例如每5分钟就有一个新的文件。 AWK的多个实例将被调用以处理/骨料上设定的时间间隔中的数据(比如每30分钟)。
cat SomeFilesWithLotsOfData | awk '
{
# process lots of data which takes a lot of time
# build up associate arrays based on input
}
END {
# Output processed data which takes little time
# Loop over associative arrays and output to persistent files
}'
说(在END语句之前)的处理部分需要30分钟才能完成(哇,这是一个很长的时间,还是让我们用它去图)。此相同的awk脚本的第二实例可以被实例化该第一一端之前处理一个新的批次的数据文件,并且其它的处理的数据需要输出到相同的文件作为前一个实例。各输出文件的确切数目awk的实例输出到是取决于输入(即,其基于在所述输入记录的特定字段)。我不想锁定所有被处理的输入之前可能的输出文件的,因为我不知道哪个awk的实例将首先完成处理事情。所以目前我计划在年底开始创建一个锁和结束后解锁,但我的实现是有点麻烦,所以我正在寻找一个卓越的方法。
有一个在Quick-and-dirty way to ensure only one instance of a shell script is running at a time类似的问题
如果你的系统中存在该命令的flock(1)
的解决方案可能是最简单的。
一种选择是简单地包裹你的awk脚本的所有调用:
flock -x /var/lock/myscriptlockfile awk ...
这将连载您awk脚本的调用,以便只有一个可以在同一时间运行。因此,它在一段时间后终止的,如果你要决定是否稍后再试,或只是跳过永远在等待,而不是可以调整flock
电话。
要允许脚本的多个副本运行,但只允许一次一个来写,你可以调整这个解决方案,您的最终中调用flock
喜欢的东西来包装所谓的“关键部分”:
awk 300>/var/lock/myscriptlockfile '
# ...
END {
system("flock -x 300");
# critical section
system("flock -u 300");
}
'