我有一个文本文件“invoice.txt”,其中包含以“供应商发票号”开头的行,其中包含 RCTI- 形式的订单号字段,后跟构成订单号的字母数字字符。
如果我输入命令:
awk '/Vendor Invoice No/ {gsub("RCTI-","",$4) ; print $4 ; exit}' /mnt/path/invoice.txt
从命令行或从 bash 中的脚本中运行它,它返回发票号码,例如 REA-0130193/2 (我们只需要 RCTI- 之后的部分,在本例中这是正确的),因此,寻求使此过程仅运行在新文件上,而不必在每次执行时对全部数量的发票文件进行操作我将其合并到一个新脚本中,其中包括inotifywait
仅对到达目录中的新文本文件进行操作,即
inotifywait -m /mnt/path -e create -e moved_to |
while read path action file; do
i="$path$file"
echo "$i"
orderno="$(awk '/Vendor Invoice No/ {gsub("RCTI-","",$4) ; print $4 ; exit}' $i)"
echo "$orderno">>test.txt
done
这也有效,当文本文件到达时,在“test.txt”中生成新的订单号。但是,如果我通过调用以下命令来运行包含此命令的脚本:
~/script.sh& or ~/script.sh &
从另一个脚本中,在这种情况下,我没有得到任何回报,这让我发疯。有谁知道为什么当它是脚本中的脚本时它会停止工作,但在直接运行时可以正常工作 - 无论是在终端中还是在后台?
更让我困惑的是,其他 awk 命令继续在同一个 script.sh 中工作,包括以下形式之一:
paidamount="$(awk '/Payment Amt/ {gsub(",","",$11) ; print $11;exit}' $i)"
echo "$paidamount">>test.txt
由于担心与特殊字符有关,我创建了一个单独的文件 orderno.awk ,其中包含以下内容:
#! /usr/bin/awk -f
/Vendor Invoice No/ {gsub("RCTI-","",$4) ; print $4 ; exit}
并通过调用它
orderno="$(~/orderno.awk $i)"
在同一脚本中,行为没有变化。
将命令写为
orderno="$(awk '/Vendor Invoice No/ {gsub(/RCTI-/,"",$4) ; print $4 ; exit}' $i)"
我可以看出没有什么区别。
答案1
因此,正如 Gordon Davisson 所建议的那样,将 inotifywait 行更改为:
inotifywait -m /mnt/path -e close_write | while read path action file; do
修复了该问题,因为现在当 awk 应用于该文件时,整个文件都存在,而不仅仅是其中的一部分。存在“竞争条件”,其中使用以前的语法,文本文件已打开用于写入,但不完整,并且仅一些应用于它的 awk 命令有效。将 inotifywait 的事件从 create 更改为 close_write 就达到了目的。