我正在编写一个shell脚本程序,我在内部调用awk脚本。这是我的下面的脚本。
for FILE in `eval echo{0..$fileIterator}`
{
if(FILE == $fileIterator)
{
printindicator =1;
}
grep RECORD FILEARRAY[FILE]| awk 'for(i=1;i<=NF;i++) {if($i ~ XXXX) {XARRAY[$i]++}} END {if(printIndicator==1){for(element in XARRAY){print element >> FILE B}}'
我希望我的代码清楚。如果您需要任何其他详细信息,请与我们联系。
问题
我在这个程序中的动机是遍历所有文件,获取所有文件中包含“XXXX”的行并将行存储在数组中。这就是我在这里所做的。最后,我需要将数组变量的内容存储到一个文件中。我可以在每个步骤存储内容,如下所示
{if($i ~ XXXX) {XARRAY[$i]++; print XARRAY[$i] >> FILE B}}
但是不采用这种方法背后的原因是每次我需要进行I / O操作时,为此花费的时间很多,这就是为什么我每次都将它转换为内存然后最后倾倒将内存数组(XARRAY)放入文件中。
我面临的问题是。 shell脚本每次调用awk,数据都存储在数组(XARRAY)中,但是对于下一次迭代,XARRAY的先前内容将被删除,并将新内容假设为新数组。因此,当我打印内容时,它只打印最近更新的XARRAY,而不是打印出预期的所有数据。
预期的建议
1)如何让awk脚本意识到XARRAY是一个旧的,而不是在每次迭代中每次调用时都是新的。
2)其中一种方法是每次都进行I / O.但我对此并不感兴趣。除此之外还有其他选择吗?谢谢。
答案 0 :(得分:0)
哎呀,不知道它是真的还是伪代码!
你不能让awk保持状态。您可能需要将其保存到临时文件中,或将其存储在shell变量中,其中的内容将传递给以后的调用。但这对我理解你想要达到的目标来说太麻烦了。
我建议您省略循环,这将允许您仅通过一些重新排序来调用awk一次。我假设FILE A是循环中的FILE,而FILE B是外部的东西。重新排序最终会形成一些非常类似的东西:
grep RECORD ${FILEARRAY[@]:0:$fileIterator} | awk 'for(i=1;i<=NF;i++) {if($i ~ XXXX) {XARRAY[$i]++}} END {for(element in XARRAY){print element >> FILEB}'
我将文件名扩展名移到grep
调用,并删除了整个printIndicator检查。
这一切都可以更有效地完成(显而易见的是删除grep
),但是你提供的细节太少,无法使早期优化变得合理。
编辑:使用更新中的信息修复循环迭代。这是一个循环解决方案,它不受新的空白问题和太长的命令行的影响:
for FILE in $(seq 0 $fileIterator); do
grep RECORD "${FILEARRAY[$FILE]}"
done |
awk 'for(i=1;i<=NF;i++) {if($i ~ XXXX) {XARRAY[$i]++}} END {for(element in XARRAY){print element >> FILEB}'
它仍然只运行awk
一次,不断从循环中提供数据。
如果要将结果加载到数组UGUGU中,请执行以下操作(需要bash 4):
mapfile UGUGU < FILEB
答案 1 :(得分:0)
results=$(for loop | awk{for(element in XARRAY)print element})..
我将结果声明为数组,因此对于正在打印的每个“元素”,它应存储在结果[1]中,结果[2]。
但不是这样,它正在执行以下...... 让我们假设 element =“我很好”(for循环的第一次迭代), element =“你好吗”(for循环的第二次迭代)。
根据这个我的预期结果是, 结果[1] =“我很好”,结果[2] =“你好吗”, 但我得到的结果是结果[1] =“我”结果[2] =“我”。我不知道为什么它会被空间划分..有关此的任何建议