我正在使用shell脚本,并且我正在使用awk脚本。我使用awk
选项从shell脚本向-v
传递参数。在某些时候,当参数大小超过某个限制时,我得到'参数列表太长错误'。这是我之前的问题,但我找到了相同的根本原因。现在我的问题是:
使用-v选项从shell传递给awk的变量=太大⟶因此获取参数列表太长错误
我的想法是将大变量分解成小块并将其存储在数组中,然后将数组传递给awk
,而不是将单个变量传递给awk
。
我的问题是:
awk
。我知道如何修改awk
脚本中的shell变量。但是如何修改awk
脚本中的shell数组呢? 我读到-v选项是不可取的,他们建议管道变量值。如果是那样的话
echo variable | awk '{}'
因此变量将被传送。但我必须管道一个数组以及其他一些变量。请你帮助我好吗?
CODE DESCRIPTION
addvariable=""
export variable
loop begins
eval $(awk -v tempvariable="$addvariable" '{tempvariable=tempvariable+"long string" variable=tempvariable(Here is where the shell variable(variable) is being modified )}')
In shell
addvariable=$variable (Taking the new value of shell variable and feeding back to awk in the next iteration)
loop ends
所以问题是现在随着add变量和变量不断增加,我得到的参数太长了错误。所以我要做的就是将tempvariable拆分成小块然后将它存储在变量[1]变量中[2]等然后将其分配给addvariable [1],addvariable [2]和feed addvariable [1],[2]而不是整个addvariable作为一个整体。所以我的问题是如何将其作为数组提供。以及如何将awk中的大数据存储到变量[1]变量[2]
中CODE addshellvariable = “”
for i in {0..10}
{
zcat normalfile{i} > FILE A
zcat hugefile{i} > FILE
export shellvariable=""
getdate=grep "XXX" FILE B|sort|Uniq (getdate contains a list of id's)
eval $(awk -v getdata="$getdata" -v addshellvariable="$addshellvariable" BEGIN {tempvariable="";split(addshellvariable,tempshellvariableArray,"*");while(t <= length(tempshellvariable)) {awkarray[tempshellvariableArray[t]];} {for(id in ids) {awkarray[id];} END {for(id in awkarray) {tempvariable=tempvariable"*"id"*"awkarray[id]} **print "shellvariable"=tempvariable;**}} FILE A)
addshellvariable=$shellvariable;
}
因为你可以看到awk被嵌入shell中。每次我需要将awkarray内容再次反馈到awk中。这样我就可以获得更新的内容了,这就是我通过打印shell shell变量获取awk数组内容的原因存储在另一个shell变量“addshellvariable”中,并在下一次迭代中被赋予awk。但问题是当shellvariable大小增加某一点然后我得到一个Argument太长的错误。因此,我想要一种解决方案,而不是做 print“shellvariable”= tempvariable; 我可以将其设为 print“shellvariable [1]”= tempvariable的一部分; 等等......
答案 0 :(得分:3)
您的shell似乎限制了您。我怀疑你的猜测是正确的,这不是一个awk问题,它是你用来调用awk的脚本语言。
您可以使用从文件加载的变量预加载awk。看看这个:
$ printf 'foo=2\nbar=3\nbaz=4\n' > vars
$ printf 'snarf\nblarg\nbaz\nsnurry\n' > text
$ awk 'NR==FNR{split($0,a,"=");vars[a[1]]=a[2];next} $1 in vars {print vars[$1]}' vars text
4
$
这是如何运作的?
前两行printf为我们提供原始数据。如果它们不完全清楚,那么在没有重定向的情况下运行它们(或者生成文件)。
awk脚本有两个主要部分。 Awk脚本包含condition { commands }
的重复。在这种情况下,我们有两个这样的集合。
第一组的条件为 NR==FNR
。如果awk正在处理的当前记录号(NR)与当前文件中的当前记录号相同,则评估为“true”。显然,这仅适用于FIRST文件,因为从第二个文件的第一行开始,NR是1加上第一个文件的行数。
在此部分中,我们根据其等号签署split()
行,并将数据放入名为vars
的数组中。
第二组的条件为 $1 in vars
,如果当前行的第一个单词作为vars
数组的下标存在,则计算结果为true。我将此仅作为你可以用变量做的一个例子,因为我不知道你想用这些变量实现什么。
这是否解决了您的问题?如果没有,我们需要查看您的一些代码,以了解如何解决它。
更新评论中的每个建议,这里证明它适用于大变量:
首先,我们准备输入数据:
$ dd if=/dev/random of=out.rand count=128k bs=1k
131072+0 records in
131072+0 records out
134217728 bytes transferred in 3.265765 secs (41098404 bytes/sec)
$ b64encode -o out.b64 out.rand out.rand
$ ls -lh out.b64
-rw-r--r-- 1 ghoti wheel 172M Jul 17 01:08 out.b64
$ awk 'BEGIN{printf("foo=")} NR>1{printf("%s",$0)} END{print ""}' out.b64 > vars
$ ls -lh vars
-rw-r--r-- 1 ghoti wheel 170M Jul 17 01:10 vars
$ wc -l vars
1 vars
$ cut -c1-30 vars
foo=orq0UgQJyUAcwJV0SenJrSHu3j
好的,我们在一条线上有一个~170MB的变量。我们把它吮吸成awk。
$ awk 'NR==FNR{split($0,a,"=");vars[a[1]]=a[2];next} END{print length(vars["foo"]);print "foo=" substr(vars["foo"],0,26);}' out.var bar
178956971
foo=orq0UgQJyUAcwJV0SenJrSHu3j
我们可以看到变量的大小,前26个字符与我们从shell中看到的匹配。是的,它有效。