请考虑以下情形:
echo 52=abcd_53=1_54=efgh_55=ijkl | awk -v time_tag="52=" -v start_time="54=" -v end_time="55=" '{p=index($0, time_tag)} {q=index($0, start_time)} {r=index($0, end_time)} /53=1/'
我想在shell变量中获取p,q,r的值,以便在执行上述命令后可以使用它们。 我无法使用shell数组,因为最终目标如下:
for line in $(cat $dir/$file | awk '/53=1')
do
for word in $(echo $line | tr "_" "\n")
do
if [ ${word:0:3} == "52=" ] ; then
time_tag=$word
elif [ ${word:0:3} == "54=" ] ; then
start_time=$word
elif [ ${word:0:3} == "55=" ] ; then
end_time=$word
fi
done
echo $time_tag","$start_time","$end_time
done
我希望将以上执行更改为以下执行,以期更快执行:
for line in $(cat $dir/$file | awk -v time_tag="52=" -v start_time="54=" -v end_time="55=" '{p=index($0, time_tag)} {q=index($0, start_time)} {r=index($0, end_time)} /53=1/')
do
echo ${line:p:7}","echo ${line:q:7}","echo ${line:r:7}
done
我认为,如果我只是在awk行本身中获取索引,由于时间是一个瓶颈,因此程序可以变得更快(数百万行)。
答案 0 :(得分:0)
除返回值之外的其他,不是,但是如何消除无用的cat
和:
$ cat file
52=abcd_53=1_54=efgh_55=ijkl
$ for i in file
do
ret=$(awk -v time_tag="52=" -v start_time="54=" -v end_time="55=" '{p=index($0, time_tag)} {q=index($0, start_time)} {r=index($0, end_time)} /53=1/{print p,q,r}' "$i")
read -r -a array <<< "$ret"
done
$ echo ${array[0]}
1
$ echo ${array[1]}
14
$ echo ${array[2]}
22
awk部分最后改变了一点:
awk -v time_tag="52=" -v start_time="54=" -v end_time="55=" '{
p=index($0, time_tag)
}
{
q=index($0, start_time)
}
{
r=index($0, end_time)
}
/53=1/ {
print p,q,r # added this and the brackets around this
}' $i
现在awk输出:
1 14 22
是array
在read
上的空间分割。
在不知道文件中包含什么以及预期输出是什么样的情况下,我真的无法做更多的事情(即,用awk完全重写它)。
答案 1 :(得分:0)
您的问题尚不清楚,但是根据您的原始脚本,我认为以下输入内容
52=abcd_53=1_54=efgh_55=ijkl
应返回以下输出:
52=abcd,54=efgh,55=ijkl
如果这是您的最终目标,则可以执行以下awk:
awk 'BEGIN{FS="[_=]";OFS=","}
{ for(i=1;i<NF;i+=2) a[$i]=$i"="$(i+1)
if(a[53]==1) print a[52],a[54],a[55]
delete a
}' file
当然,这假定您的所有行都是这样。
如果要使用bash脚本处理类似的事情,则可以使用while循环直接处理此输出
awk '{...}' file | while IFS=, read -r time_tag start_time end_time; do
do what you want to do
done
如果要快速执行,请使用awk
进行所有操作,并将其输出传递到bash循环: