AWK按变量值打印字段

时间:2014-04-02 09:51:07

标签: bash variables awk field

所以我有一个GET命令从服务器检索数据,只需要这些信息的特定部分。

我有一个工作脚本,但awk部分很长,我想知道我是否可以帮助缩短它。

当前脚本:

curl  --insecure -u $HMCUSER:$HMCPASS -H "Accept: */*" -H "Content-type: application/json" -s --header "X-API-Session:$COOKIE" -X GET https://$HMCIP:6794$BCID1/blades | awk -F\" '{print $50" M1:"$42"\n"$114" M1:"$106"\n"$18" M1:"$10"\n"$98" M1:"$90"\n"$34" M1:"$26"\n"$82" M1:"$74"\n"$66" M1:"$58"\n"$130" M1:"$122}' > ~walkers/blade-info-new

echo -e "\n`cat blade-info-new`\n"

,输出为:

  

/ api / blades / 394a7ea8-02d4-11e1-b71a-5cf3fcad1a40 M1:B.1.01

     

/ api / blades / 749f35cc-02d7-11e1-946a-5cf3fcad1ef8 M1:B.1.02

     

/ api / blades / eeae9670-02d5-11e1-a5ee-5cf3fcad21e0 M1:B.1.03

     

/ api / blades / 3949f5a0-02d4-11e1-85df-5cf3fcad1dc8 M1:B.1.04

     

/ api / blades / d25df328-02d3-11e1-a1e9-5cf3fcad2158 M1:B.1.05

     

/ api / blades / bbecebd8-02d0-11e1-aca7-5cf3fcacf4a0 M1:B.1.06

     

/ api / blades / 3016b5d8-02d7-11e1-a66f-5cf3fcad1dd0 M1:B.1.07

     

/ api / blades / 75796586-02ea-11e1-8ab0-5cf3fcacf040 M1:B.1.08

(有两列:/ api / blades / ...和M1:B.1.0#)

所以我尝试了这个:

for i in {10..130..8}
do
     try=$(curl  --insecure -u $HMCUSER:$HMCPASS -H "Accept: */*" -H "Content-type: application/json" -s --header "X-API-Session:$COOKIE" -X GET https://$HMCIP:6794$BCID1/blades | awk -v i=$i -F\" '{print $i}')
     echo "$try"
done

希望得到与上面相同的输出,而不是我得到完整的JSON对象:

  

{ “叶片”:[{ “状态”: “操作”, “名称”: “B.1.03”, “类型”: “系统-X”, “对象-URI”:“/ API /叶片/ eeae9670-02d5-11e1-a5ee-5cf3fcad21e0 “},{” 状态 “:” 操作 “ ”名称“: ”B.1.05“, ”类型“: ”系统-X“, ”对象-URI“:”/ API /blades/d25df328-02d3-11e1-a1e9-5cf3fcad2158"},{"status":"operating","name":"B.1.01","type":"system-x","object-uri“: “/api/blades/394a7ea8-02d4-11e1-b71a-5cf3fcad1a40"},{"status":"operating","name":"B.1.07","type":"system-x","object- URI “:”/ API /叶片/ 3016b5d8-02d7-11e1-a66f-5cf3fcad1dd0 “},{” 状态 “:” 操作”, “名称”: “B.1.06”, “类型”: “系统-X”, “对象-URI”: “/ API /叶片/ bbecebd8-02d0-11e1-aca7-5cf3fcacf4a0”},{ “状态”: “操作”, “名称”: “B.1.04”, “类型”:“系统 - X”, “对象-URI”: “/ API /叶片/ 3949f5a0-02d4-11e1-85df-5cf3fcad1dc8”},{ “状态”: “操作”, “名称”: “B.1.02”, “类型”: “系统-X”, “对象-URI”: “/ API /叶片/ 749f35cc-02d7-11e1-946a-5cf3fcad1ef8”},{ “状态”: “操作”, “名称”: “B.1.08”,”类型 “:” 系统-X”, “对象-URI”: “/ API /叶片/ 75796586-02ea-11e1-8ab0-5cf3fcacf040”}]}

所以我想知道如何让变量工作?我去过很多网站,每个人似乎都说awk -v i=$i应该工作......

编辑:我要打印的序列是对象uri(即/ api / blades / ...),后跟刀片名称(即B.1.01)。这些信息都在curl命令返回的JSON对象中,从第十个字段开始,之后是每个第8个字段(使用“作为分隔符”):

{ “叶片”:[{ “状态”: “操作”, “名称”: “的 B.1.03 ”, “类型”: “系统-X”, “对象-URI” : “的 / API /叶片/ eeae9670-02d5-11e1-a5ee-5cf3fcad21e0 ”},{ “状态”: “操作”, “名称”:“的 B.1.05 “ ”类型“: ”系统-X“, ”对象-URI“: ”的 / API /叶片/ d25df328-02d3-11e1-a1e9-5cf3fcad2158 “},{ ”状态“:” 操作“ ”名称“: ”的 B.1.01 “, ”类型“: ”系统-X“, ”对象-URI“:” 的 / API /叶片/ 394a7ea8-02d4-11e1- b71a-5cf3fcad1a40 “},{” 状态 “:” 操作 “ ”名称“: ”的 B.1.07 “, ”类型“: ”系统-X“,” 对象-URI “:” 的 / API /叶片/ 3016b5d8-02d7-11e1-a66f-5cf3fcad1dd0 “},{” 状态 “:” 操作 “ ”名称“:” 的 B.1.06 “ ”类型“: ”系统-X“, ”对象-URI“: ”的 / API /叶片/ bbecebd8-02d0-11e1-aca7-5cf3fcacf4a0 “},{ ”状态“:”操作 “ ”名称“: ”的 B.1.04 “, ”类型“: ”系统-X“, ”对象-URI“:” 的 / API /叶片/ 3949f5a0-02d4-11e1 -85df-5cf3fcad1dc8 “},{” 状态 “:” 操作 “ ”名称“: ”的 B.1.02 “,”类型 “:” 系统-X “ ”对象-URI“: ”的 / API /叶片/ 749f35cc-02d7-11e1-946a-5cf3fcad1ef8 “},{ ”状态“: ”操作“,”命名 “:” 的 B.1.08 “ ”类型“: ”系统-X“, ”对象-URI“:” 的 / API /叶片/ 75796586-02ea-11e1-8ab0-5cf3fcacf040 “}]}

刀片名称不必按数字顺序排列(B.1.01至B.1.08),仅与相应的ID位于同一行

编辑2:找到了解决方法。使用C类型循环而不是普通bash:for (( i=10; i<=130; i+=8 ))而不是for i in {10..130..8}

4 个答案:

答案 0 :(得分:2)

这个问题的正确答案是抛弃awk(即使我喜欢awk)并使用真正的JSON解析器,例如非常方便的jq工具。

答案 1 :(得分:1)

如果我理解正确,您希望扩展{10..130..8}以提供所需的$ i值系列。

在我的bash版本中(它是ooooold:3.2.25),字符串{10..130..8}不会扩展为任何内容,因此输入循环时i =“{10..130 .. 8}“所以awk使用$ {10..130..8},它似乎简化为$ 0(即整个curl返回字符串)。因此你的问题。您可以通过将echo $i放入循环中来测试是否是这种情况。

您需要更好的方法来获取所需的一系列值。您可以使用“seq”(man seq获取更多信息)。 $( seq 10 8 130 )应该这样做。

此外,你可以这样做,以便curl只用一些像杂乱的东西一样调用一次 # Construct the string of fields for i in $( seq 10 8 130 ); do fields="$fields,\$$i" done fields=$( echo "$fields" | sed 's/^,//' ) # Remove the leading comma ...curl command... | awk '{print '$fields'}'

答案 2 :(得分:0)

如何更改记录分隔符(RS),以及定义要引用的字段分隔符。然后保存名称,并与object-url一起打印。下面的命令应该给你一个起点

curl [...] | awk -v RS=, -F\" '{
    if ($2 ~ /^name$/) {name=$4}
    if ($2 ~ /^object-uri$/) {print name, $4}
}'

P.S。远程if&#39;如果你想看看RS =如何帮助你打印$ 0。

答案 3 :(得分:0)

我想你想让awk访问i变量的更新值。因为awk指令在撇号之间(&#39;&#39;),所以i的值在awk中是隐藏的,但是你可以通过从被替换的指令中删除撇号来避免它。我的实际价值。它在this online AWK manual的动态变量部分中进行了解释。

因此,对于您的特定情况,您可以尝试

  

awk -F \&#34; &#39; {print $&#39; $ i&#39;}&#39;

而不是

  

awk -v i = $ i -F \&#34; &#39; {print $ i}&#39;

在管道命令的末尾。