在shell脚本中使用时存储在awk中

时间:2012-07-11 18:16:49

标签: shell awk grep

我正在编写一个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.但我对此并不感兴趣。除此之外还有其他选择吗?谢谢。

2 个答案:

答案 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] =“我”。我不知道为什么它会被空间划分..有关此的任何建议