अंतिम पंक्ति मिलान में हेरफेर करें


2

मैं किसी पाठ में मेल खाते हुए अंतिम पंक्ति में कैसे हेरफेर कर सकता हूं? मेरे पास एक कॉन्फ़िगरेशन फ़ाइल है जिसमें मैं एक निश्चित मूल्य को बदलना चाहता हूं:

val1=0
val2=a
val3=?
val2=lol

मैं केवल मूल्य के लिए grep से मेल खाते अंतिम पंक्ति को बदलना चाहता हूं। sed -i 's/\(^val2=\)/\1yes/'एक अच्छी शुरुआत है, लेकिन val2केवल आखिरी के बजाय दोनों लाइनों को बदल देता है ।

मैंने सवाल को बहुत उदारता से यूनिक्स के रूप में टैग किया क्योंकि मैं किसी भी समाधान के लिए खुला हूं: sed या awk, Perl या Ruby, Bash या जो भी हो। एक छोटा समाधान एक कौर से कामुक है।

जवाबों:


1

मैं इसके साथ आया सबसे अच्छा है:

tac config |while read LINE; do
  if [ "$DONE" != 1 ] && echo "$LINE" |grep '^\s*val2\s*=' >/dev/null; then
    echo "$LINE" |sed 's/^\(\s*val2\s*=\s*\)/\1yes/'
    DONE=1
  else
    echo "$LINE"
  fi
done |tac >config.new

लेकिन इस तरह के एक सामान्य कार्य के लिए मुझे जल्दी और गंदी पाइपलाइन पसंद नहीं है।


1

यहां मिली स्क्रिप्ट के आधार पर :

sed -r ':0;/^val2=/!b;:1;$!N;/\n.*word/{h;s/\n[^\n]*$//p;g;s/^.*\n//};$!b 1;s/^(.*)(val2=)[^\n]*/\1\2yes/' file

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

@wilhelmtell: मैंने डॉट को अंत में नॉन-न्यूलाइन में बदल दिया [^\n]। दुबारा प्रयास करें।
डेनिस विलियमसन

1

सामान्य विचार: द्वारा विभाजित विखंडू में इनपुट पढ़ें \nval2=। अंतिम भाग को छोड़कर, जहाँ हम टेक्स्ट को पहली नई पंक्ति में बदलते हैं, हर छाँट को प्रिंट करें। यहाँ एक अपेक्षाकृत सरल gawk समाधान है जो अधिकांश मामलों को संभालता है:

gawk -v 'RS=\nval2=' -v ORS= \
  'RT {print $0 RT} !RT {sub(/[^\n]*/, "yes"); print $0}'

यह मानता है कि पहली पंक्ति के साथ शुरू नहीं होता है val2=और कम से कम एक मैच है। दोनों दोषों को ठीक करने से स्क्रिप्ट काफी जटिल हो जाती है:

gawk -v 'RS=\nval2=' -v ORS= \
  '!RT {if (NR==1) sub(/^val2=[^\n]*/, "val2=yes"); else sub(/[^\n]*/, "yes")}
   {print $0 RT}'

यहां एक समान सामान्य सिद्धांत पर आधारित पर्ल समाधान है, लेकिन एक ही बार में पूरी फ़ाइल को पढ़ना है। मुझे यह स्पष्ट लगता है क्योंकि इसमें विशेष मामलों (खाली फ़ाइल के अलावा) को संभालने की आवश्यकता नहीं है।

perl -e 'undef $/;
         @chunks = split /(?=^val2=)/m, <>;
         $chunks[@chunks-1] =~ s/(?<=^val2=).*/yes/ if @chunks;
         print @chunks'

पर्ल के विस्तारित रेगेक्स के साथ, हम एकल रेगेक्सपी प्रतिस्थापन का उपयोग कर सकते हैं। बस ^val2=उस मैच का अनुसरण करें जो दूसरे द्वारा नहीं किया गया है ^val2=:

perl -e 'undef $/; $_=<>; s/^val2=.*\n(?!.*\nval2=)/val2=yes\n/m; print'

मैंने पायथन का लाभ लेने की कोशिश की, rsplitजो अंतिम एन क्षेत्रों को विभाजित कर सकता है, लेकिन जब मैंने इसे अधिक क्रिप्टिक किए बिना काम नहीं कर पाया, तो मेरे पर्ल समाधान।


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