Text-Processing

jq + 從 json 文件中列印屬性而不刪除必要的反斜杠

  • June 3, 2018

我們有以下 json 文件:

more file.json

{
 "href" : "http://master02:8080/api/v1/clusters/HDP/configurations?type=kafka-env&tag=version1527250007610",
 "items" : [
   {
     "href" : "http://master02:8080/api/v1/clusters/HDP/configurations?type=kafka-env&tag=version1527250007610",
     "tag" : "version1527250007610",
     "type" : "kafka-env",
     "version" : 8,
     "Config" : {
       "cluster_name" : "HDP",
       "stack_id" : "HDP-2.6"
     },
     "properties" : {
       "content" : "\n#!/bin/bash\n\n# Set KAFKA specific environment variables here.\n\n# The java implementation to use.\nexport JAVA_HOME={{java64_home}}\nexport PATH=$PATH:$JAVA_HOME/bin\nexport PID_DIR={{kafka_pid_dir}}\nexport LOG_DIR={{kafka_log_dir}}\nexport KAFKA_KERBEROS_PARAMS={{kafka_kerberos_params}}\nexport JMX_PORT=9997\n# Add kafka sink to classpath and related depenencies\nif [ -e \"/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar\" ]; then\n  export CLASSPATH=$CLASSPATH:/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar\n  export CLASSPATH=$CLASSPATH:/usr/lib/ambari-metrics-kafka-sink/lib/*\nfi\n\nif [ -f /etc/kafka/conf/kafka-ranger-env.sh ]; then\n. /etc/kafka/conf/kafka-ranger-env.sh\nfi",
       "is_supported_kafka_ranger" : "true",
       "kafka_log_dir" : "/var/log/kafka",
       "kafka_pid_dir" : "/var/run/kafka",
       "kafka_user" : "kafka",
       "kafka_user_nofile_limit" : "128000",
       "kafka_user_nproc_limit" : "65536"
     }
   }
 ]

我們建構以下 jq 語法以列印 file.json 中的屬性

jq -r '.items[].properties | to_entries[]
      | "\"\(.key)\" : \"\(.value | gsub("\n";"\\n"))\","' file.json


"content" : "\n#!/bin/bash\n\n# Set KAFKA specific environment variables here.\n\n# The java implementation to use.\nexport JAVA_HOME={{java64_home}}\nexport PATH=$PATH:$JAVA_HOME/bin\nexport PID_DIR={{kafka_pid_dir}}\nexport LOG_DIR={{kafka_log_dir}}\nexport KAFKA_KERBEROS_PARAMS={{kafka_kerberos_params}}\nexport JMX_PORT=9997\n# Add kafka sink to classpath and related depenencies\nif [ -e "/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar" ]; then\n  export CLASSPATH=$CLASSPATH:/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar\n  export CLASSPATH=$CLASSPATH:/usr/lib/ambari-metrics-kafka-sink/lib/*\nfi\n\nif [ -f /etc/kafka/conf/kafka-ranger-env.sh ]; then\n. /etc/kafka/conf/kafka-ranger-env.sh\nfi",
"is_supported_kafka_ranger" : "true",
"kafka_log_dir" : "/var/log/kafka",
"kafka_pid_dir" : "/var/run/kafka",
"kafka_user" : "kafka",
"kafka_user_nofile_limit" : "128000",
"kafka_user_nproc_limit" : "65536",

但問題是輸出在雙倍配額之前沒有反斜杠

例子

而是在輸出中輸入以下行

[ -e \"/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar\" ]

我們得到輸出:(沒有必要的反斜杠)

[ -e "/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar" ]

請建議如何相應地修復 jq 語法

. . .

預期結果範例:

預期產出

   "content" : "\n#!/bin/bash\n\n# Set KAFKA specific environment variables here.\n\n# The java implementation to use.\nexport JAVA_HOME={{java64_home}}\nexport PATH=$PATH:$JAVA_HOME/bin\nexport PID_DIR={{kafka_pid_dir}}\nexport LOG_DIR={{kafka_log_dir}}\nexport KAFKA_KERBEROS_PARAMS={{kafka_kerberos_params}}\nexport JMX_PORT=9997\n# Add kafka sink to classpath and related depenencies\nif [ -e \"/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar\" ]; then\n  export CLASSPATH=$CLASSPATH:/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar\n  export CLASSPATH=$CLASSPATH:/usr/lib/ambari-metrics-kafka-sink/lib/*\nfi\n\nif [ -f /etc/kafka/conf/kafka-ranger-env.sh ]; then\n. /etc/kafka/conf/kafka-ranger-env.sh\nfi",
   "is_supported_kafka_ranger" : "true",
   "kafka_log_dir" : "/var/log/kafka",
   "kafka_pid_dir" : "/var/run/kafka",
   "kafka_user" : "kafka",
   "kafka_user_nofile_limit" : "128000",
   "kafka_user_nproc_limit" : "65536"

jq 有幾種轉義模式,您可以使用它來代替您自己的引用。

jq -r '.items[].properties | to_entries[] | (.key | @json) + ": " + (.value|@json) + ","' file.json

產生你想要的輸出,我想。格式化程序根據@json需要添加引號和反斜杠以保留 JSON 有效的語法,包括雙引號字元串:

"content": "\n#!/bin/bash\n\n# Set KAFKA specific environment variables here.\n\n# The java implementation to use.\nexport JAVA_HOME={{java64_home}}\nexport PATH=$PATH:$JAVA_HOME/bin\nexport PID_DIR={{kafka_pid_dir}}\nexport LOG_DIR={{kafka_log_dir}}\nexport KAFKA_KERBEROS_PARAMS={{kafka_kerberos_params}}\nexport JMX_PORT=9997\n# Add kafka sink to classpath and related depenencies\nif [ -e \"/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar\" ]; then\n  export CLASSPATH=$CLASSPATH:/usr/lib/ambari-metrics-kafka-sink/ambari-metrics-kafka-sink.jar\n  export CLASSPATH=$CLASSPATH:/usr/lib/ambari-metrics-kafka-sink/lib/*\nfi\n\nif [ -f /etc/kafka/conf/kafka-ranger-env.sh ]; then\n. /etc/kafka/conf/kafka-ranger-env.sh\nfi",

這裡唯一需要的原始字元串操作是添加“:”;否則它只是將鍵/值輸入過濾器並處理所有引用。您也可以使用@json "\(.key): \(.value),",儘管我發現這種行為比它的價值更麻煩。


如果最後一行多餘的逗號有問題,請將這些值收集在一起改用join(str)

jq -r '.items[].properties | [to_entries[] | @json "\(.key): \(.value)"] | join(",\n")' file.json

這會將所有字元串放入一個數組中,然後放在,\n每對之間。

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