अंतिम टिप्पणी लाइन से सभी लाइनों को 'फू' के साथ लाइन में टिप्पणी करें


12

एक पाठ फ़ाइल पर विचार करें users.txt:

#alice
#bob
charlie
dotan
eric

मुझे (अनन्य) अंतिम टिप्पणी वाली पंक्ति (समावेशी) से सब कुछ टिप्पणी करने की आवश्यकता है dotan। यह परिणाम है:

#alice
#bob
#charlie
#dotan
eric

क्या ऐसा करने के लिए एक अच्छा sedऑनलाइनर है? मैं किसी भी उपकरण के साथ खुश रहूंगा, न कि sedवास्तव में।

वर्तमान में मुझे अंतिम टिप्पणी की पंक्ति संख्या इस प्रकार मिल रही है:

$ cat -n users.txt | grep '#' | tail -n1
  2 #bob

मैं फिर एक जोड़ता हूं और टिप्पणी करता हूं sed:

$ sed -i'' '3,/dotan/ s/^/#/' users.txt

मुझे पता है कि मैं चालाक हो सकता हूं और यह सब एक साथ bcएक बदसूरत वन-लाइनर में डाल सकता हूं । निश्चित रूप से एक क्लीनर तरीका होना चाहिए?

जवाबों:


5

कैसा रहेगा

perl -pe '$n=1 if s/^dotan/#$&/; s/^[^#]/#$&/ unless $n==1;' file

या, awk में एक ही विचार:

awk '(/^dotan/){a=1; sub(/^/,"#",$1)} (a!=1 && $1!~/^#/){sub(/^/,"#",$1);}1; ' file

7

यदि मौजूदा टिप्पणी की गई पंक्तियाँ एक एकल सन्निहित ब्लॉक बनाती हैं, तो आप पहली टिप्पणी पंक्ति के बजाय मेल कर सकते हैं , केवल उन पंक्तियों को टिप्पणी करना-बाहर करना और जिसमें आपके अंतिम पैटर्न शामिल हैं जो पहले से ही टिप्पणी नहीं किए गए हैं

sed '/^#/,/dotan/ s/^[^#]/#&/' file

यदि मौजूदा टिप्पणियां सन्निहित नहीं हैं, तो मुझे लगता है कि सेड रेंज मैच के लालची स्वभाव के कारण आपको कुछ करने की आवश्यकता होगी

tac file | sed '/dotan/,/^#/ s/^[^#]/#&/' | tac

यानी अंत पैटर्न से ऊपर की ओर 'पहली' टिप्पणी से मेल खाते हैं - जाहिर है कि यह इतना सुविधाजनक नहीं है यदि आप एक जगह समाधान चाहते हैं।


4

आप दोनों मामलों को संभाल सकते हैं (एक एकल संदर्भ ब्लॉक में टिप्पणी की गई लाइनें या एक ही sedआह्वान के साथ असुविधाजनक रेखाओं के बीच में फैला हुआ) :

sed '1,/PATTERN/{/^#/{x;1d;b};//!{H;/PATTERN/!{1h;d};//{x;s/\n/&#/g}}}' infile

यह 1,/PATTERN/रेंज में केवल लाइनों को प्रोसेस करता है। यह xस्थान परिवर्तन w को बदलता है। पैटर्न स्पेस हर बार एक लाइन पर टिप्पणी की जाती है (इसलिए होल्ड बफर में एक से अधिक कॉमेंटेड लाइन कभी नहीं होती है) और हर उस लाइन को जोड़ देती है, जो Hपुराने स्पेस (जब पहली लाइन पर हो, 1dऔर क्रमशः 1hशुरुआती को हटाने के लिए भी आवश्यक नहीं है) पकड़ बफर में खाली लाइन)।
जब यह PATTERN से मेल खाने वाली लाइन तक पहुँच जाता है, तो यह इसे Hपुराने बफर में भी जोड़ देता है , e बफ़र xको बदलता है और फिर \nपैटर्न स्पेस में हर ewline कैरेक्टर को \newline और a से बदलता है #(यानी, पैटर्न स्पेस की सभी लाइनें अब से शुरू होंगी #, होल्ड स्पेस में पहली लाइन के रूप में पहली पंक्ति को शामिल करना हमेशा एक टिप्पणी लाइन होती है)।
एक नमूने के साथ infile:

alice
#bob
bill
#charlie
ding
dong
dotan
jimmy
#garry

चल रहा है:

sed '1,/dotan/{                   # if line is in this range    -start c1
/^#/{                             # if line is commented        -start c2
x                                 # exchage hold space w. pattern space
1d                                # if 1st line, delete pattern space
b                                 # branch to end of script
}                                 #                             -end c2
//!{                              # if line is not commented    -start c3
H                                 # append to hold space
/dotan/!{                         # if line doesn't match dotan -start c4
1h                                # if 1st line, overwrite hold space
d                                 # delete pattern space
}                                 #                             -end c4
//{                               # if line matches dotan       -start c5
x                                 # exchage hold space w. pattern space
s/\n/&#/g                         # add # after each newline character
}                                 #                             -end c5
}                                 #                             -end c3
}' infile                         #                             -end c1

आउटपुट:

alice
#bob
bill
#charlie
#ding
#dong
#dotan
jimmy
#garry

इसलिए यह #charlie(और शामिल) से केवल (और बाहर) और केवल dotanअन्य लाइनों को अछूता छोड़ने वाली टिप्पणी कर रहा है।
ज़रूर, यह मानता है कि लाइन मिलान से पहले हमेशा कम से कम एक टिप्पणी लाइन होती है PATTERN। यदि ऐसा न हो तो आप प्रतिस्थापन से पहले एक अतिरिक्त जाँच जोड़ सकते हैं:/^#/{s/\n/&#/g}


धन्यवाद, मुझे इस उत्तर से बहुत कुछ सीखना होगा!
१२:

रुको, मैंने पंगा लिया होगा। यह टिप्पणी की गई लाइनों की अंतिम श्रृंखला के बारे में नहीं है ? नहीं, मैं समझ गया, यह है। अंतिम श्रृंखला + डॉटन। बहुत चालाक चतुर।
मिकसेर्व

1
आपको हमेशा सबसे अच्छे सवाल मिलते हैं। धिक्कार है डॉटन मुझे थोड़ी देर के लिए फेंक दिया था - शायद अभी भी करता है, मैं अभी तक यह परीक्षण किया havent। धन्यवाद, डॉन।
मिकसेर्व जूल

2

यहाँ एक और है sed:

sed  -e:n -e'/\n#.*\ndotan/!{$!{N;/^#/bn'      \
-eb  -e\} -e'/^#/s/\(\n\)\(dotan.*\)*/\1#\2/g' \
-et  -e\} -eP\;D <in >out

जैसा आप पूछते हैं। यह केवल एक स्टैक पर काम करता है - इसे आवश्यक रूप से और जब तक आवश्यक हो, तब तक टिप्पणी की गई लाइनों की घटनाओं के बीच, और जब यह एक मिल जाए, तो इनपुट में आगे नई टिप्पणी लाइन के पक्ष में पुराने बफर को डंप करना। चित्र...

यहाँ छवि विवरण दर्ज करें

क्षमा करें, मुझे नहीं पता कि मैंने ऐसा क्यों किया। लेकिन यह ध्यान में आया।

वैसे भी, sedकिसी भी श्रृंखला में प्रत्येक अंतिम टिप्पणी लाइन के बीच अपने बफ़र्स को फैलाता है, कभी भी इसके बफर में एक भी अधिक को बनाए रखने की तुलना में अंतिम टिप्पणी की घटना को सही ढंग से ट्रैक करने के लिए आवश्यक नहीं है, और यदि किसी भी समय यह अंतिम पंक्ति का सामना करता है तो ऐसा करने का प्रयास करेगा अंतिम gलोबाल निष्पादन विवरण और शाखा tपूरे बफर को मुद्रित करने के लिए बाहर ले जाती है, अन्यथा यह Pउन सभी पंक्तियों को चीर देगा जो यह अपने बफर से रिलीज होते ही करता है।

मुझे लगता है कि यह मन में समझौते लाया है ...

printf %s\\n   \#alice \#bob charlie dotan eric \
               \#alice \#bob charlie dotan eric \
               \#alice \#bob charlie dotan eric |
sed  -e:n -e'l;/\n#.*\ndotan/!{$!{N;/^#/bn'     \
-eb  -e\} -e'/^#/s/\(\n\)\(dotan.*\)*/\1#\2/g'  \
-et  -e\} -eP\;D

#alice
#alice\n#bob$
#alice\n#bob\ncharlie$
#alice\n#bob\ncharlie\ndotan$
#alice
#bob\ncharlie\ndotan$
#bob\ncharlie\ndotan\neric$
#bob\ncharlie\ndotan\neric\n#alice$
#bob\ncharlie\ndotan\neric\n#alice\n#bob$
#bob\ncharlie\ndotan\neric\n#alice\n#bob\ncharlie$
#bob\ncharlie\ndotan\neric\n#alice\n#bob\ncharlie\ndotan$
#bob
charlie\ndotan\neric\n#alice\n#bob\ncharlie\ndotan$
charlie
dotan\neric\n#alice\n#bob\ncharlie\ndotan$
dotan
eric\n#alice\n#bob\ncharlie\ndotan$
eric
#alice\n#bob\ncharlie\ndotan$
#alice
#bob\ncharlie\ndotan$
#bob\ncharlie\ndotan\neric$
#bob\ncharlie\ndotan\neric\n#alice$
#bob\ncharlie\ndotan\neric\n#alice\n#bob$
#bob\ncharlie\ndotan\neric\n#alice\n#bob\ncharlie$
#bob\ncharlie\ndotan\neric\n#alice\n#bob\ncharlie\ndotan$
#bob
charlie\ndotan\neric\n#alice\n#bob\ncharlie\ndotan$
charlie
dotan\neric\n#alice\n#bob\ncharlie\ndotan$
dotan
eric\n#alice\n#bob\ncharlie\ndotan$
eric
#alice\n#bob\ncharlie\ndotan$
#alice
#bob\ncharlie\ndotan$
#bob\ncharlie\ndotan\neric$
#bob
#charlie
#dotan
eric

इस कमांड और ऊपर वाले के बीच केवल एक अंतर है और वह है lशीर्ष पर ook कमांड। हम जब lसे OOK sedके पैटर्न स्थान के रूप में यह काम करता है हम और पर्दे के पीछे क्या पर चला जाता है का एक बेहतर विचार कैसे अपने प्रयासों को निर्देशित करने के लिए की एक बेहतर समझ प्राप्त कर सकते हैं।

इस मामले में हम sedस्टैक इनपुट देख सकते हैं जब तक कि इनपुट की दूसरी घटना नहीं मिली है \n#.*\ndotan, और यह कि जब यह एक बार में पिछले लाइन को प्रिंट करना शुरू करता है। यह थोड़े शांत है। मैंने इस पर बहुत काम किया।


बहुत बढिया आपको धन्यवाद! स्पष्टीकरण के साथ अंतिम पैराग्राफ बहुत अच्छा है, मैं इस पोस्ट से सीखने में काफी समय व्यतीत करूंगा। अच्छा ढेर!
dotancohen

1
@dotancohen - यह एक बहुत अच्छा सवाल था। स्टैक को देखने के लिए संपादन पर एक नज़र डालें ।
चाटुकार

2
मैं संपादित इतिहास में प्रविष्टि को नोटिस करता हूं Handle many dotans। मुझे यकीन है कि यह मेरी पत्नी का सबसे बुरा सपना है।
19anc में dotancohen

1
@dotancohen - हाँ, यह एक कठिन था। #\ndotan\ndotanइन चीजों के लिए सामान होना कठिन है। मेरा यह मतलब है कि जब मैं यह एक अच्छा सवाल कहता हूं। मुझे लगता है कि मुझे यह बिल्कुल सही मिला, लेकिन एक समस्या जो आप चला सकते हैं यदि आपकी टिप्पणी ब्लॉक 1000 लाइनों द्वारा अलग हो जाती है - जो धीमा हो जाएगी । उदाहरण के लिए, यदि आप 150 रेखाओं तक फैले हैं तो बफर को तोड़ने से s/\n/&/150;tपहले आप कुछ ऐसा चिपका सकते हैं /\n#। और वैसे भी, शायद यह वही है जो वह सभी के लिए इंतजार कर रहा है !
मिकसेर्व
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.