2012-04-07 9 views
25

मैं गिट का उपयोग कर रहा हूं, फिर सर्वर पर जेएसओएन पेलोड के रूप में प्रतिबद्ध संदेश और अन्य बिट्स पोस्ट कर रहा हूं।बैश में वर्णों से बचने (JSON के लिए)

वर्तमान में मेरे पास है:

Calendar can't go back past today 

तो

curl -i -X POST \ 
    -H 'Accept: application/text' \ 
    -H 'Content-type: application/json' \ 
    -d "{'payload': {'message': '$MSG'}}" \ 
    'https://example.com' 

मेरे असली JSON क्षेत्रों में से एक और जोड़ी है:

MSG=`git log -n 1 --format=oneline | grep -o ' .\+'` 

जो की तरह कुछ करने के लिए एमएसजी सेट।

यह ठीक काम करता है, लेकिन निश्चित रूप से जब मेरे पास एक एडिट्रोफ़ के साथ उपरोक्त एक प्रतिबद्ध संदेश है, तो JSON अमान्य है।

मैं बैश में आवश्यक पात्रों से कैसे बच सकता हूं? मैं भाषा से परिचित नहीं हूं, इसलिए मुझे यकीन नहीं है कि कहां से शुरू करना है। के साथ ' को प्रतिस्थापित करने पर कम से कम मुझे संदेह होगा।

+4

एक अतिरिक्त नोट के रूप में, JSON डबल (एकल नहीं) का उपयोग करने के लिए ऊपर अस्वीकार होगा मूल्यों, इतने सारे (लेकिन सभी नहीं) पारसर्स के आसपास उद्धरण माना जाता है, भले ही यह संरचना की दृष्टि से ध्वनि और तों था ठीक से caped। – polm23

उत्तर

9

ठीक है, पता चला कि क्या करना है। बैश इस अपेक्षाकृत अपेक्षाकृत समर्थन करता है, हालांकि हमेशा के रूप में, वाक्यविन्यास वास्तव में बहुत अनुमानित नहीं है!

मूलतः ${string//substring/replacement} रिटर्न क्या आप छवि चाहते हैं, ताकि आप

MSG=${MSG//\'/\\\'} 

उपयोग कर सकते हैं ऐसा करने के लिए। अगले समस्या यह है कि पहले regex अब और काम नहीं करता है, लेकिन उस

git log -n 1 --pretty=format:'%s' 

साथ बदला जा सकता अंत में, मैं यहां तक ​​कि उन्हें बचने के लिए जरूरत नहीं थी। इसके बजाए, मैंने बस 'JSON में \ "को बदल दिया। ठीक है, आप हर दिन कुछ सीखते हैं।

+0

यह पूरी तरह से अनुपालन JSON से बचने का कोई मतलब नहीं है। असली चीज़ को टैब को '\ t' के साथ प्रतिस्थापित करने की आवश्यकता है, नई लाइनों को '\ n' के साथ प्रतिस्थापित किया जाना चाहिए, शाब्दिक बैकस्लाश को दोगुना किया जाना चाहिए, आदि –

2

मैं ऐसा ही कुछ पाया:

MSG=`echo $MSG | sed "s/'/\\\\\'/g"` 
+0

एमएसजी ठीक होने के समाप्त होता है - मुझे लगता है कि मैं बस कुछ ऐसा करना चाहता हूं जैसे MSG = MSG.replace ("'", "\'"), लेकिन यह सुनिश्चित नहीं है कि बैश में ऐसा कैसे करें। –

+0

यहां कुछ बिंदु http://www.cyberciti.biz/faq/unix-linux-replace-string-words-in-many-files/ हैं। हो सकता है कि आप इसे तेजी से समझ सकें – user907860

12

मैं जेएसओएन का उपयोग करके स्थानांतरण के लिए बैश में वर्णों से बचने की कोशिश कर रहा था, जब मैं इस पर आया। मुझे मिला वहाँ वास्तव में है कि एक बड़ा list of characters that must be escaped – खासकर यदि आप मुक्त रूप पाठ को संभालने के लिए कोशिश कर रहे हैं

दो सुझाव दिए जो मुझे उपयोगी होते हैं:।

  • उपयोग बैश ${string//substring/replacement} वाक्य रचना इस सूत्र में वर्णित
  • । वास्तविक नियंत्रण ch का प्रयोग करें टैब, न्यू लाइन, गाड़ी वापसी, आदि में vim के लिए aracters आप Ctrl +वी वास्तविक नियंत्रण कोड के बाद (Ctrl +मैं उदाहरण के लिए टैब के लिए) टाइप करके इन डाल सकते हैं।

    JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\\/\\\\} # \ 
    JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\//\\\/} #/
    JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\'/\\\'} # ' (not strictly needed ?) 
    JSON_TOPIC_RAW=${JSON_TOPIC_RAW//\"/\\\"} # " 
    JSON_TOPIC_RAW=${JSON_TOPIC_RAW// /\\t} # \t (tab) 
    JSON_TOPIC_RAW=${JSON_TOPIC_RAW// 
    /\\\n} # \n (newline) 
    JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^M/\\\r} # \r (carriage return) 
    JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^L/\\\f} # \f (form feed) 
    JSON_TOPIC_RAW=${JSON_TOPIC_RAW//^H/\\\b} # \b (backspace) 
    

    मैं इस स्तर पर बाहर नहीं काम किया है कैसे सही ढंग से यूनिकोड वर्ण से बचने के लिए जो भी (जाहिरा तौर पर) की आवश्यकता होती है:

परिणामी बैश प्रतिस्थापन मैं के साथ आया था इस प्रकार हैं।अगर मैं इसे काम करता हूं तो मैं अपना जवाब अपडेट कर दूंगा।

+0

अन्यथा सुझाव के संबंध में कि आप -d पैरामीटर और @ संशोधक का उपयोग करते हैं कर्ल के साथ, यह समस्या का समाधान नहीं करता है। मैं वास्तव में पहले से ही इसका उपयोग कर रहा था और पाया कि फ़ाइल की सामग्री को जेएसओएन की अपेक्षा के अनुसार ठीक से एन्कोड किया जाना चाहिए। – xsgordon

20

डेटा को सही ढंग से उद्धृत करने के तरीके के बारे में चिंता करने के बजाय, बस इसे फ़ाइल में सहेजें और का निर्माण करें curl--data विकल्प के साथ अनुमति देता है। यह सुनिश्चित करने के लिए कि JSON मान के रूप में उपयोग के लिए git का उपयोग ठीक से बच निकला है, JSON उत्पन्न करने के लिए मैन्युअल रूप से इसे बनाने के बजाय jq जैसे टूल का उपयोग करें।

jq --arg msg "$(git log -n 1 --format=oneline | grep -o ' .\+')" \ 
    '{payload: { message: $msg }}' > git-tmp.txt 

curl -i -X POST \ 
    -H 'Accept: application/text' \ 
    -H 'Content-type: application/json' \ 
    -d @git-tmp.txt \ 
    'https://example.com' 

आप -d @- का उपयोग कर मानक इनपुट से भी सीधे पढ़ सकते हैं; मैं इसे git से पढ़ने वाली पाइपलाइन बनाने के लिए पाठक के लिए एक अभ्यास के रूप में छोड़ देता हूं और curl के साथ अपलोड करने के लिए सही पेलोड संदेश उत्पन्न करता हूं।

:

+0

सही; मैंने इस जवाब को तब लिखा जब मैंने यह जवाब लिखा था। मैं अब अपडेट करूंगा। – chepner

41

अजगर का उपयोग करना (संकेत यह jq ... | curl ... [email protected] 'https://example.com' है):

यह समाधान शुद्ध बैश नहीं है, लेकिन यह गैर इनवेसिव है और यूनिकोड संभालती है।

json_escape() { 
    printf '%s' $1 | python -c 'import json,sys; print(json.dumps(sys.stdin.read()))' 
} 

ध्यान दें कि JSON मानक अजगर पुस्तकालयों का हिस्सा है और एक लंबे समय के लिए किया गया है, तो यह एक बहुत कम से कम अजगर निर्भरता है।

या का उपयोग कर PHP: तो जैसे

json_escape() { 
    printf '%s' $1 | php -r 'echo json_encode(file_get_contents("php://stdin"));' 
} 

उपयोग:

$ json_escape "ヤホー" 
"\u30e4\u30db\u30fc" 
+0

क्या यह वास्तव में एक JSON प्रारूप है जिसे पहले पैरामीटर के रूप में पारित किया जा रहा है, या यह एक पायथन ऑब्जेक्ट प्रारूप है? क्या दोनों के बीच एक सराहनीय अंतर है? –

+1

पहला पैरामीटर केवल एक स्ट्रिंग होना चाहिए जो आउटपुट जेएसओएन में एक साधारण मूल्य होगा, न कि एक जटिल ऑब्जेक्ट, जैसे मूल प्रश्न में। यदि आप एक जटिल मूल्य बैश डालना चाहते हैं तो इसके लायक होने की तुलना में लगभग निश्चित रूप से अधिक परेशानी होती है। – polm23

+1

मुझे यह पसंद है। इसे सरल ऑनलाइनर में बदलने में मुश्किल नहीं है: 'उर्फ json_escape = "पायथन-सी' आयात जेसन, sys; प्रिंट json.dumps (sys.stdin.read()) '' –

3

सबसे आसान तरीका jshon पार्स करने के लिए एक कमांड लाइन उपकरण का उपयोग कर रहा है, पढ़ सकते हैं और JSON बनाने

jshon -s 'Your data goes here.' 2>/dev/null

4
git log -n 1 --format=oneline | grep -o ' .\+' | jq --slurp --raw-input 

उपरोक्त पंक्ति मेरे लिए काम करता है। https://github.com/stedolan/jq और jq उपकरण

0

मुझे प्रतिबद्धता के बाद प्रतिबद्ध संदेश के साथ एक संदेश भेजने का एक ही विचार था। सबसे पहले मैंने कोशिश की कि यह वही ऑटोर जैसा था। लेकिन बाद में एक बेहतर और सरल समाधान मिला।

बस PHP फ़ाइल बनाई गई है जो संदेश भेज रही है और उसे wget के साथ कॉल करें। हुक में /उत्तर प्राप्त करते हैं:

wget -qO - "http://localhost/git.php" 
Git में

।php:

chdir("/opt/git/project.git"); 
$git_log = exec("git log -n 1 --format=oneline | grep -o ' .\+'"); 

और फिर JSON बना सकते हैं और पीएचपी शैली में कर्ल फोन

0

यह वह जगह है एक भागने समाधान पर्ल का उपयोग कर कि U+0000U+001F को बैकस्लैश (\), दोहरे-उद्धरण (") और नियंत्रण वर्ण निकल जाता है:

$ echo -ne "Hello, \n\tBye" | \ 
    perl -pe 's/(\\(\\\\)*)/$1$1/g; s/(?!\\)(["\x00-\x1f])/sprintf("\\u%04x",ord($1))/eg;' 
Hello, \u000a\u0009Bye 
संबंधित मुद्दे