对由多个子进程填充的文件进行准确编号和计数



我有一个脚本,可以调用另一个脚本的多个实例。这些子进程都写入同一个文件,我想要一种准确的方法来计算该文件中的行并对其进行编号。

这些子进程在完成后还会将其退出代码写入单独的文件中,这就是我跟踪它们的方式。父脚本有一个"无限"while 循环,该循环读取包含退出代码的文件,直到行数 = 子脚本实例数。

这个想法是子进程不可预测地在同一文件"log.txt"中写入"行"。

所以我尝试让他们每个人在日志上做一个 grep -c.txt检查当前的"行"数量,并添加一个:

parent_script.sh

#!/bin/bash
for (( i=1; i<=10; i++ ))
do
child_script.sh
done
certain_check=0
while [[ `wc -l < exitfile.txt` -le 10 ]]; do
if [[ `wc -l < exitfile.txt` -eq 10 ]]; then
certain_check=$(( $certain_check + 1 ));
fi
[[ $certain_check -eq 2 ]] && break;
done

child_script.sh

#!/bin/bash
for (( i=1; i<=100; i++ ))
do
if [[ ! -f log.txt ]]; then
counter=1;
else
counter=$(( `grep -c "line" log.txt` + 1 ));
fi
echo $counter" line";
echo $counter" line" >> log.txt;
sleep 0.$RANDOM;
done

这工作得很好,但它时不时地会连续两次使用相同的数字,可能是因为两个子进程同时写入文件。之后,"grep -c"会拾取适量的行并从长远来看自行纠正。

有没有人不得不做类似的事情,也许比我有更好的主意? 提前谢谢你!

编辑:上面的脚本是简化的。真正的子脚本是一个作业,它通过一些其他工具从源数据库复制表的架构,在目标数据库上创建表,并通过数据流将数据从源表传输到目标表(数据库也位于不同的服务器上)。父脚本只是调用多个实例并管理它们,以便可以同时处理更多表。

这就是为什么我想在终端和文件中实时显示以下内容的原因:

1) Loading table A
2) Loading table B
3) Loading table C

每个子脚本都有一个表列表作为参数,因此每个子脚本将处理更多表,并且根据它们的大小,一个子进程可以处理三个表,而另一个子进程尚未完成它的第一个表。

对它们进行编号的想法是了解还剩下多少张表,因为有些作业处理的表甚至超过 2000 张。此外,我试图避免"等待"机制,因为这些机制会影响整体性能。

我希望这些额外的细节可以消除一些困惑!

虽然我当时没有意识到这一点,但我的男人@shellter有一个绝妙的主意。我通过让每个子脚本写入它自己的日志文件来解决这个问题,从而避免了两个实例同时在同一文件中写入的情况,然后我只是继续处理这些文件,一个接一个,逐行,检查未编号的行,在那个"无限而循环"中。

parent_script:

#!/bin/bash
for (( i=1; i<=10; i++ ))
do
child_script.sh
done
certain_check=0
tbl_count=1;
while [[ `wc -l < exitfile.txt` -le 10 ]]; do
for (( r=0; r<=9; r++ ))
do
[[ -f log$r.txt ]] && cat log$r.txt >> parent_log.txt && rm -f log$r.txt;
if [[ -f parent_log.txt ]]; then
while grep -q ^"Loading" parent_log.txt > /dev/null;
do      
a=`grep ^"Loading" parent_log.txt | head -1`;
echo "${tbl_count}) $a
";
sed "s/^$a/${tbl_count}) $a/" parent_log.txt > tmpfile.txt;
cat tmpfile.txt > parent_log.txt;
rm -f tmpfile.txt;
tbl_count=$(( $tbl_count + 1 ));
done
fi
done
if [[ `wc -l < exitfile.txt` -eq 10 ]]; then
certain_check=$(( $certain_check + 1 ));
fi
[[ $certain_check -eq 2 ]] && break;
done

父脚本为每个子脚本创建目录,例如 transfer0、transfer1、transfer2 等。实例编号是从子脚本中的目录名称中提取的:

child_script:

#!/bin/bash
ind=`pwd | sed 's|.*/(.*)|1|' | sed 's/transfer(.*)/1/'`;
for (( i=1; i<=100; i++ ))
do
if [[ ! -f log.txt ]]; then
counter=1;
else
counter=$(( `grep -c "line" log.txt` + 1 ));
fi
echo $counter" line";
echo $counter" line" >> log$ind.txt;
sleep 0.$RANDOM;
done

显然,在实际脚本中还有更多内容。但这是主要思想。@shellter,向你致敬!

最新更新