रेगीक्स कैप्चर ग्रुप कंटेंट को सेड का उपयोग करके बदलें


16

मैं अपने nginx.conf फ़ाइल को प्रोग्रामेटिक रूप से संपादित करने की कोशिश कर रहा हूं, जिसमें इस तरह की एक पंक्ति है:

        access_log /var/log/nginx/access.log;

जो मैं इस तरह दिखना चाहता हूं:

        access_log /dev/stdout;

मेरा मानना ​​है कि रेगेक्स एक कैप्चर ग्रुप में पार्ट ^\s*access_log([^;]*);को कैप्चर करेगा /var/log/nginx/access.log, लेकिन मुझे यकीन नहीं है कि कैप्चर ग्रुप को सही तरीके से सेड के साथ कैसे बदला जाए?

मैंने कोशिश की

echo "        access_log /var/log/nginx/access.log;" | sed 's/^\s*access_log([^;]*);/\1\\\/dev\\\/stdout/'

लेकिन मुझे त्रुटि मिल रही है:

sed: -e expression #1, char 45: invalid reference \1 on `s' command's RHS

अगर मैं कोशिश करता हूं sed -rतो कोई त्रुटि नहीं है, लेकिन आउटपुट वह नहीं है जिसकी मुझे उम्मीद है:

 /var/log/nginx/access.log\/dev\/stdout

मैं कैप्चर ग्रुप और व्हाट्सएप के साथ स्मार्ट बनने की कोशिश कर रहा हूं और सीधे "access_log /var/log/nginx/access.log;" यदि वितरण डिफ़ॉल्ट लॉग फ़ाइल स्थान को बदलता है।


1
sed '/access_log/s|/[^;]\+|/dev/stdout|'
कोस्टा

@ कोस्टस यदि आप ऐसा कर सकते हैं तो एक उत्तर मैं आपको इस तरह से भी काम दूंगा!
अबे वोल्कर

जवाबों:


16

वहाँ गलतियों की एक जोड़ी।

सबसे पहले, के बाद से sedउपयोग करता है बुनियादी नियमित अभिव्यक्ति, आप की जरूरत \(है और \)एक पर कब्जा समूह बनाने के लिए। -rस्विच नियमित अभिव्यक्ति बढ़ाया सक्षम जिसके कारण आप त्रुटि नहीं मिलता है। देखें कि मुझे रेगीक्स के पात्रों के रूप में व्याख्या करने के लिए रीजेक्स वर्णों से बचने की आवश्यकता क्यों है?

दूसरा, आप कैप्चर ग्रुप को गलत जगह पर डाल रहे हैं। अगर मैं आपको सही तरीके से समझूं, तो आप ऐसा कर सकते हैं:

sed -e 's!^\(\s*access_log\)[^;]*;!\1 /dev/stdout;!' your_file

!आगे के स्लैश से बचने के लिए रेगेक्स डेलिमिटर के रूप में उपयोग पर ध्यान दें /dev/stdout


धन्यवाद, अद्भुत काम करता है! मैं इसे अभी तक स्वीकार नहीं कर पाया हूं, लेकिन ऐसा करने के लिए 9 मिनट में वापस आ जाएगा।
अबे वोल्कर

1
@AbeVoelker आपका बहुत स्वागत है। मैं खुश हूं कि मैं मदद कर सका।
जोसेफ आर।

5

अपने regexp में आपको पता होना चाहिए कि कोष्ठक के भीतर पैटर्न \No.का पिछला संदर्भ है ()। तो regexp होना चाहिए's@^(\s*access_log ).*$@\1/dev/stdout/;@'

मैं पेशकश कर सकता हूँ

sed '/access_log/s|/[^;]\+|/dev/stdout|'

सुझाव: क्या आप /उस पितर के अंदर उपयोग करने का इरादा रखते हैं जो आप s///हर उस प्रतीक के लिए बदलने के लिए स्वतंत्र हैं जिसे आप s###उदाहरण के लिए चाहते हैं


धन्यवाद, काश मैं दो उत्तर स्वीकार कर पाता! मुझे अब समाधान देखने के बाद मदद मांगने से पहले पूरी तरह से मैन पेज न पढ़ने का अफसोस है।
अबे वोल्कर 21

3

इसे पकड़ने के बजाय, बस इसे क्यों नहीं ढूंढा जाए और एक स्थानापन्न करना है? अर्थात:

sed "/access_log/ s| /.*;| /dev/stdout;|"

यह उन रेखाओं की खोज करता है जो " access_log" तब किसी भी रेखा पर होती हैं जो इसे " /whatever/path/is/there;" के साथ " /dev/stdout;" से बदल देगी

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.