Awk

如果 awk 中不存在欄位,則添加輸入

  • May 4, 2022

我在用

awk -F'[":]' '$2=="id"{printf("pri,%s,",$5)}$2=="name"{printf("%s,",$5)}$2=="objectId"{printf$4}$2=="polledName"{print$5}' | sed -e 's/, /,/g'

這變成了

 }, {
   "id" : "1",
   "name" : "host1",
   "objectId" : 0001,
   "polledName" : "192.168.1.1"
 }, {
   "id" : "2",
   "name" : "host2",
   "objectId" : 0002,
   "polledName" : "192.168.1.2"
 }, {
   "id" : "3",
   "name" : "host3",
   "objectId" : 0003,
 }, {
   "id" : "4",
   "name" : "host4",
   "objectId" : 0004,
   "polledName" : "192.168.1.3"
 }, {

進入這個

pri,1,host1,0001,192.168.1.1
pri,2,host2,0002,192.168.1.2
pri,3,host3,0003,pri,4,host4,0004,192.168.1.3

知道如何修改它,以便當 polledName 的條目不存在時,它轉到下一行而不是換行到目前行,即如果 $5 什麼都不返回,則添加一個換行符。


這是上面的程式碼,上面的 awk 腳本列印gawk -o-得很漂亮,因此清晰易讀:

awk -F'[":]' '
   $2 == "id" {
           printf "pri,%s,", $5
   }
   
   $2 == "name" {
           printf "%s,", $5
   }
       
   $2 == "objectId" {
           printf $4
   }
   
   $2 == "polledName" {
           print $5
   }
' | sed -e 's/, /,/g'

如果您真的必須使用awk,請為 polledName 設置/取消設置變數

awk -F'[":]' '$2 == "id" {if(lf) print "" ; printf("pri,%s,",$5); lf=1;}
              $2 == "name" {printf("%s,",$5)}
              $2 == "objectId" {gsub(" ","",$4); printf "%s", $4}
              $2 == "polledName" {print $5; lf=0; }
              END {if(lf) print "" ;}' 

這基本上是你的程式碼有點擴展,我補充說:

  • 帶有“id”if(lf) print "" ;的行列印一個新行,如果lf不是零;lf=1: 放lf
  • 帶有“polledName”的可選行:lf=0;遇到行時清除 lf。
  • 根據評論使用print ""(請注意,print沒有參數列印目前/最後一行)
  • 從 $4添加gsub(" ","",$4);到剝離空間(空間保留為分隔符是非空間)

請注意,這awk是解析 json(或 xml)文件的糟糕解決方案。

您在生成此 json 文件的程序上進行中繼,欄位順序可能會更改,特別是如果您在封閉的伺服器或設備中。

對於任何有權訪問在命令行上使用 JSON 的適當工具的人*,*您可以使用以下方法將欄位提取到引用的 CSV 數據集中jq

$ jq -r '.[] | [ "pri", .id, .name, .objectId, .polledName ] | @csv' file
"pri","1","host1",1,"192.168.1.1"
"pri","2","host2",2,"192.168.1.2"
"pri","3","host3",3,
"pri","4","host4",4,"192.168.1.3"

這假設問題中顯示的數據是頂級數組的一部分並且格式正確(問題中的第三個元素包含無效的尾隨逗號):

[
   {"id":"1","name":"host1","objectId":1,"polledName":"192.168.1.1"},
   {"id":"2","name":"host2","objectId":2,"polledName":"192.168.1.2"},
   {"id":"3","name":"host3","objectId":3},
   {"id":"4","name":"host4","objectId":4,"polledName":"192.168.1.3"}
]

如果您想要一個帶引號的空字元串來代替缺失值,請將表達式.polledName更改為. 如果鍵不可用(或者如果它的值為),這將使用空字元串而不是值。.polledName``jq``.polledName // ""``null``null

更改@csv@tsv輸出運算符以獲取製表符分隔的值。

使用 JSON 感知工具執行此操作的好處是您將在輸出中獲得解碼的字元串,而不是 JSON 編碼的數據。此外,嵌入的引號等會自動正確處理,並且 JSON 輸入是在單行上還是以其他特殊方式格式化都沒有關係。

引用自:https://unix.stackexchange.com/questions/701373