【发布时间】:2014-11-04 23:56:48
【问题描述】:
我必须处理一些大文件并在每一行上运行多个测试。我目前正在使用 awk 运行单个测试,并使用“while-read-line-do”循环将每一行传递给十几个 so awk 命令,这些命令测试各个列以验证其内容并记录错误。通过所有测试的行将附加到 .VALID 文件中。
我目前面临的问题是这个过程非常缓慢。在阅读了网络上和 StackOverflow 上的许多其他帖子后,我收集到的信息是,主要的罪魁祸首是“while-read-line-do”循环,它不会将文件(每个大约 100K 行)借入内存。
我希望这里有人可以帮助我找出更好的实现方法,以便我可以获得类似 awk 的性能。这是我的代码的简化版本:
while read line || [[ -n "$line" ]];do
echo $line | awk -F\; '{
if ( ($3 != "P") && ($3 != "0") ) {print $0 "; ERROR ;" >> "INPUT_FILE.ERRORS"};
else print $0 >> "INPUT_FILE.OK";
}'
echo $line | awk -F\; '{
if ( ($7 < 10) || ($7 > 3) ) {print $0 "; ERROR ;" >> "INPUT_FILE.ERRORS"};
else print $0 >> "INPUT_FILE.OK";
}'
echo $line | awk -F\; '{
if ( ($36 < 0) || ($36 > 1000) ) {print $0 "; ERROR ;" >> "INPUT_FILE.ERRORS"};
else print $0 >> "INPUT_FILE.OK";
}'
done < INPUT_FILE.txt
理想情况下,我正在尝试提出一种解决方案,允许我使用基于 awk 的循环在每行中进行多次传递。
提前致谢。
【问题讨论】:
-
只需将所有 awk 块/测试放入一个脚本中,不要使用
next或任何内容来跳过该行。 awk 针对每一行运行所有块。您根本不需要多次运行 awk 或读取循环。 -
嗨@EtanReisner。感谢您的快速回复。我不太确定如何使用 awk 遍历行,而不是“while read line do”。你能不能放过我一点,分享一个简单的例子。再次感谢!
-
if ( ($7 < 10) || ($7 > 3) )在这种情况下似乎存在错误,因为它始终为真。应该是&&而不是||? -
你不会在 awk 中循环。 awk 为您循环。 awk 在每一行上自动运行你给它的整个脚本。只需给它文件和所有块/模式/if语句/等。
-
@TimZimmermann 我构建了一个简单的例子,因为我的条件有点复杂。