मैं किसी फ़ाइल से सभी टिप्पणियां कैसे निकाल सकता हूं?


21

मेरे पास टिप्पणियों के साथ एक फ़ाइल है:

foo
bar
stuff
#Do not show this...
morestuff
evenmorestuff#Or this

मैं केवल सभी अपूर्ण कोड प्रिंट करना चाहता हूं:

foo
bar
stuff
morestuff
evenmorestuff

एक फ़ाइल से टिप्पणियों को स्ट्रिप करने में सक्षम होना बहुत महत्वपूर्ण है ... इसे करने का एक अच्छा तरीका क्या है?


1
आप grep के साथ एक पंक्ति के कुछ हिस्सों को नहीं निकाल सकते। आप इसके लिए sed का उपयोग कर सकते हैं
चमत्कार 173

2
आपका पाठ और आपका उदाहरण विरोधाभास। आप उन पंक्तियों के बारे में लिखते हैं, जिन पर आप टिप्पणी करते हैं, लेकिन स्पष्ट रूप से अंतिम पंक्ति से आपका मतलब पंक्ति भागों से है। और फिर एक टिप्पणी के साथ पहली पंक्ति ईओएल सहित हटा दी जाती है, और दूसरी दूसरी हो सकती है, लेकिन यह स्पष्ट नहीं है कि यह अंतिम पंक्ति है। कृपया सटीक और सटीक रूप से अपने उदाहरणों की अवहेलना करने के लिए 'पंक्तियों की टिप्पणी की'।
एंथन

5
प्रयोग करके देखें awk -F\# '$1!="" { print $1 ;} '
आर्कमेयर

2
एक लाइन को कैसे echo '#' # output a #संभाला जाएगा?
Kusalananda

3
@ प्रश्न मैं चतुर हो सकता हूं, लेकिन मैं एक शेल-व्याकरण-पार्सर चतुर नहीं लिख रहा हूं।
Kusalananda

जवाबों:


40

सभी टिप्पणियों को हटाने का एक तरीका विकल्प के grepसाथ उपयोग करना -oहै:

grep -o '^[^#]*' file

कहाँ पे

  • -o: प्रिंट केवल लाइन के भाग से मेल खाते हैं
  • पहला ^: लाइन की शुरुआत
  • [^#]*: #बार-बार शून्य या अधिक बार छोड़कर कोई भी वर्ण

ध्यान दें कि खाली लाइनें भी हटा दी जाएंगी, लेकिन केवल रिक्त स्थान वाली लाइनें ही रहेंगी।


2
मैं उपयोग करता हूंgrep -v '^#' file > newfilewithoutcomments
बेसिल स्टारीनेवविच

1
यह ध्यान दिया जाना चाहिए कि यह शेल स्क्रिप्ट के लिए एक सामान्य तरीका नहीं है, उदाहरण के लिए लाइन somvar='I am a long complicated string ## with special characters' # and I am a commentको सही तरीके से नहीं संभाला जाएगा।
वाइल्डकार्ड

यह संस्करण मेरे लिए (एक मैक पर) बेहतर काम करता है:grep -o '^[^#].*' file
पियरज़

टिप्पणियाँ चली गई हैं, लेकिन मैं आउटपुट में उनके स्थान पर सफेद स्थान का एक गुच्छा देख रहा हूं? sedसमाधान केवल एक रिक्त रेखा है, अन्य उत्तर का उपयोग करने के लिए एक ठोस तर्क की तरह लगता है, जब तक कि मैं कुछ याद नहीं कर रहा हूं?
जेब्लिन

@JBallin क्या आपने grepशायद कुछ अन्य लोगों के लिए परिभाषित किया था ? बदलने का प्रयास करें grepकरने के लिए command grep, अगर आप अभी भी रिक्त स्थान पोस्ट नमूना इनपुट देखते हैं।
जिमीज

31

मेरा मानना ​​है कि sedइससे बेहतर काम हो सकता है grep। कुछ इस तरह:

sed '/^[[:blank:]]*#/d;s/#.*//' your_file

व्याख्या

  • sedडिफ़ॉल्ट रूप से लाइन द्वारा आपकी फ़ाइल लाइन को देखेगा और संभवतः उद्धरणों में परिवर्तनों को लागू करने के बाद प्रत्येक पंक्ति को प्रिंट करेगा। ( sed '' your_fileबस सभी लाइनों को अपरिवर्तित प्रिंट करेगा)।
  • यहां हम sedप्रत्येक लाइन पर प्रदर्शन करने के लिए दो कमांड दे रहे हैं (वे एक अर्धविराम द्वारा अलग किए गए हैं)।
  • पहला आदेश कहता है /^[[:blank:]]*#/d:। अंग्रेजी में, इसका मतलब है कि अगर लाइन अपनी शुरुआत में किसी हैश से मेल खाती है (अग्रणी रिक्त स्थान के किसी भी संख्या से पहले), तो उस लाइन को हटा दें (यह मुद्रित नहीं किया जाएगा)।
  • दूसरी आज्ञा है s/#.*//:। अंग्रेजी में यह है कि एक हैश मार्क के रूप में कई चीजों के बाद विकल्प के रूप में आप पा सकते हैं (लाइन के अंत तक, वह है) कुछ भी नहीं (अंतिम दो के बीच खाली जगह नहीं है //)।
  • सारांश में, यह आपकी फ़ाइल हटाने वाली लाइनों के माध्यम से चलेगा जिसमें पूरी तरह से टिप्पणियां शामिल हैं और उसके बाद जो भी लाइनें शेष हैं, उनमें से टिप्पणियां बाहर निकल जाएंगी।

1
यह एक स्ट्रिंग के अंदर हैश के बाद मिली किसी भी चीज़ को हटा देगा , नहीं? Eg mystring="Hello I am a #hash" बन जाएगा mystring="Hello I am a"
javadba

@ जजदबा, हां, लेकिन उस बिंदु पर आप पूर्ण पार्सर का उपयोग कर सकते हैं। इस डेटा का उपयोग करने वाला है जो उद्धरण और चर असाइनमेंट को समझ सकता है लेकिन टिप्पणियों को संभाल नहीं सकता है ? (यही कारण है कि कई कॉन्फिग फाइल्स जैसे कि crontabकेवल फुल-लाइन कमेंट्स की इजाजत देते हैं, बिना प्रमुख व्हाट्सएप के, लेकिन एक लाइन पर कमेंट करने की अनुमति नहीं देते हैं। लॉजिक बहुत आसान है। इस उत्तर में केवल दो सेड निर्देशों में से पहला प्रयोग करें। crontab टिप्पणी स्ट्रिपर के लिए।)
वाइल्डकार्ड

महान उत्तर, यह सामान्य उपयोग के मामलों की एक विस्तृत सरणी के लिए उपयोगिता बनाम जटिलता के एक महान संतुलन की तरह दिखता है, लेकिन उस मामले में जब आप समय से पहले जानते हैं कि आपको केवल #(कॉलम 1 में) के साथ शुरू होने वाली लाइनों को हटाने की आवश्यकता है वहाँ का कोई लाभ है sedसे अधिक grep -v "^#"?
RBF06

4

आप sed कमांड का उपयोग करके आवश्यक आउटपुट प्राप्त कर सकते हैं। नीचे की कमान ने मेरे लिए चाल चली थी।

sed 's/#.*$//g' FileName

कहाँ पे

  • #.*$- Regexp #लाइन के अंत तक शुरू होने वाले सभी स्ट्रिंग को फ़िल्टर करेगा

यहां हमें उन पंक्तियों को हटाने की आवश्यकता है ताकि हम खाली 'लंघन' प्रतिस्थापन के साथ बदल दें।

  • g - फ़ाइल के अंत तक पैटर्न की बार-बार खोज का उल्लेख करना।

Sed का सामान्य सिंटैक्स: s/regexp/replacement/flags FileName


2
नोट: 4 लाइन को इस मामले में नई लाइन से बदल दिया गया।
α atsнιη

1
प्रयास करें कि एक स्क्रिप्ट है कि युक्त sedआदेश ...
Kusalananda

यह संभाल नहीं होगाprint "#tag" # Print a hashtag.
रे बटरवर्थ

3

जैसा कि अन्य लोगों ने बताया है, अगर किसी स्क्रिप्ट के कुछ हिस्से टिप्पणियों की तरह दिखते हैं लेकिन वास्तव में नहीं हैं तो sed और अन्य टेक्स्ट-आधारित टूल अच्छी तरह से काम नहीं करेंगे। उदाहरण के लिए, आप एक स्ट्रिंग के अंदर एक # पा सकते हैं, या सामान्य $#और ${#param}

मैंने shfmt नामक एक शेल फॉर्मेटर लिखा , जिसमें कोड को छोटा करने की सुविधा है। जिसमें अन्य बातों के अलावा टिप्पणियाँ निकालना शामिल है:

$ cat foo.sh
echo $# # inline comment
# lone comment
echo '# this is not a comment'
[mvdan@carbon:12] [0] [/home/mvdan]
$ shfmt -mn foo.sh
echo $#
echo '# this is not a comment'

पार्सर और प्रिंटर गो पैकेज हैं, इसलिए यदि आप एक कस्टम समाधान चाहते हैं, तो टिप्पणियों को सटीक तरीके से हटाने के लिए 20-लाइन गो कार्यक्रम लिखना काफी आसान होना चाहिए।


2

आप इनवर्ट मैच का उपयोग इस तरह कर सकते हैं:

    #grep -v "#" filename

-v, --invert- मैच गैर-मिलान लाइनों का चयन करने के लिए, मिलान की भावना को उल्टा करें। -v POSIX द्वारा निर्दिष्ट किया गया है।)


2
@alinh उत्तर की समीक्षा के लिए धन्यवाद। कृपया ध्यान दें कि प्रश्न न केवल लाइन की शुरुआत बल्कि फ़ाइल में कहीं भी आवश्यक है। यह भी ऊपर के प्रश्न में उसका अपेक्षित परिणाम दिखा रहा है। मेरा जवाब गलत होगा यदि मैं केवल लाइन की शुरुआत के लिए देखता हूं।
रज़ा

zzz। मेरा बुरा, अंतिम पंक्ति नहीं देखा :(
alinh

1
यह evenmorestuffओपी के उदाहरण से शुरू होने वाली रेखा को पूरी तरह से हटा देगा ।
जोसेफ आर।

@JosephR। अच्छी पकड़। इससे पहले मैं चूक गया था। इस मामले grep -o '^[^#]*' fileमें सबसे अच्छा समाधान होगा। यह पहले से ही jimmij द्वारा समझाया गया है। आपकी समीक्षा के लिए धन्यवाद
रज़ा

यह संभाल नहीं होगाprint "#tag" # Print a hashtag.
रे बटरवर्थ

2

मुझे जोसेफ का जवाब पसंद है लेकिन इसे स्ट्रिप // कमेंट्स की जरूरत है इसलिए मैंने इसे थोड़ा संशोधित किया और रेडहैट पर परीक्षण किया

# no comments alias
alias nocom="sed -E '/^[[:blank:]]*(\/\/|#)/d;s/#.*//' | strings"

# example
cat SomeFile | nocom | less

मैं शर्त लगाता हूं कि तार का उपयोग करने से खाली लाइनों को हटाने का एक बेहतर तरीका है, लेकिन यह मेरे द्वारा उपयोग किया जाने वाला त्वरित और गंदा समाधान था।

-cheers


यह संभाल नहीं होगाprint "#tag" # Print a hashtag.
रे बटरवर्थ


1
cat YOUR_FILE | cut -d'#' -f1

यह #कॉलम विभाजक के रूप में उपयोग करता है और केवल पहला कॉलम रखता है (जो कि पहले सब कुछ है #)।


1
यदि YOUR_FILEकोई स्क्रिप्ट उन आदेशों से युक्त होती है, तो स्क्रिप्ट cat YOUR_FILE | cut -'उस लाइन पर फ़ाइल में चली जाएगी ।
Kusalananda

1

जैसे अभिव्यक्ति का उपयोग करें

egrep -v "#|$^" <file-name> 

: -v: इनवर्ट मैच करेगा

: #: सभी लाइनों से मेल खाएगा

: $ ^: सभी खाली लाइनों से मेल खाएगा


1
नहीं, #वसीयत लाइन पर कहीं भी मेल खाएगी, और पूरी लाइन को हटा देगी।
ilkachachu

1

कमांड का उपयोग करने के लिए सबसे अच्छा समाधान होगा:

sed -i.$(date +%F) '/^#/d;/^$/d' ntp.conf

-I एक जगह संपादित है, लेकिन उपसर्ग सीधे निम्नलिखित एक बैकअप बनाने के लिए sed को बताता है। इस तिथि विस्तार (ntp.conf.date) के साथ हम एक पते की जगह के साथ दो कमांड चलाते हैं, पहला टिप्पणी लाइनों को हटाता है और दूसरा, अर्ध-कोलन द्वारा पहले से अलग किया गया, रिक्त लाइनों को हटाता है।

मुझे यह समाधान मिला: theurbanpenguin.com


0

अन्य जवाबों में से कोई भी यह न्याय नहीं करता है, वे या तो खाली लाइनों में छोड़ देते हैं, या उन लाइनों में छोड़ देते हैं जहां टिप्पणी पहले चरित्र में नहीं है। मैंने इसका उपयोग करते हुए समाप्त किया:

cat << EOF >> ~/.bashrc
alias nocom='sed -e "/^\s*#/d" -e "/^\s*$/d"'
EOF

यह एक उपनाम स्थापित करता है, ताकि आपको इसे याद नहीं करना पड़े (जो कि शुरू करना असंभव है)। एक नया सत्र खोलें, और आपके पास नया nocomकमांड होगा। तब आप बस कर सकते हैं

nocom /etc/foobar.conf

चीयर्स।


1
.*$पहले रेगेक्स में मिलान करने के लिए बहुत कुछ नहीं है - लंगर उपयोगी नहीं है और आप प्रतिस्थापन में उपयोग करने के लिए मिलान किए गए पाठ को कैप्चर नहीं कर रहे हैं। बस का उपयोग करें^\s*
जेफ स्कालर

यह संभाल नहीं होगाprint "#tag" # Print a hashtag.
रे बटरवर्थ

0

जोसेफ आर। के 2 उत्तर के बाद, मैं /^$/dरिक्त पंक्ति को हटाने के लिए जोड़ता हूं ।

sed '/^[[:blank:]]*#/d;s/#.*//;/^$/d'

-1

मैं पोस्ट कर रहा हूं कि मेरे लिए क्या काम करता है और दूसरों के माध्यम से, स्पष्टीकरण के साथ पढ़ने के बाद, सबसे अधिक समझ में आता है। कुछ पोस्ट करीब आए, लेकिन मैं अभी तक टिप्पणी नहीं कर सका (क्योंकि मैं एक नया हूँ):

grep -E -v "(^#.*|^$)" filename
  • -E = एग्रेप का उपयोग करने के समान एक नियमित अभिव्यक्ति के रूप में निम्न पैटर्न की व्याख्या करें
  • -v = पैटर्न के व्युत्क्रम को प्रिंट करें (ऐसी रेखाएं जो अभिव्यक्ति से मेल नहीं खातीं) मुद्रित की जाएंगी
  • "(^#.*|^$)"= इसमें एक पाइप है जो OR स्टेटमेंट को डिजाइन करता है। यह अभिव्यक्ति किसी भी लाइन को प्रिंट करने के लिए कहती है जो #(और उसके बाद कुछ भी) के साथ शुरू होती है या लाइन के शुरुआत और अंत के बीच शून्य वर्णों के साथ कोई भी रेखा।

-vस्क्रीन पर इस बात का उलट है, जो अक्षरों के साथ किसी भी लाइन है कि एक साथ शुरू नहीं करता हो जाएगा प्रिंट होगा #


यह संभाल नहीं होगाprint "#tag" # Print a hashtag.
रे बटरवर्थ

आह, ठीक है ... बिल्कुल। यह बात बताने के लिए धन्यवाद। मैं इस तरह के pam.d configs के रूप में ठेठ लिनक्स विन्यास फाइल के संबंध में एक जवाब के लिए देख रहा था, इसलिए मैंने ऐसा नहीं सोचा था। मुझे लगता है कि कोड के रूप में एक ही पंक्ति पर झूठ बोलने वाली किसी भी टिप्पणी को खोजने और निकालने के लिए इसे अनुकूलित करना होगा। मैंने अभी ऊपर अपने विशेष मुद्दे के लिए शायद एक बेहतर समाधान देखा: egrep -v "# | $ ^ ^"
jackbmg Oct.33/
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.