मैं किसी फ़ाइल में अंतिम n लाइनें कैसे संपादित कर सकता हूं?


10

क्या कोई कमांड है जो मुझे एक फ़ाइल में अंतिम एन लाइनों को संपादित करने की अनुमति देगा? मेरे पास कई फाइलें हैं, जिसमें सभी की अलग-अलग लाइनें हैं। लेकिन मैं प्रत्येक फ़ाइल में अंतिम एन लाइनों को संशोधित करना चाहूंगा। लक्ष्य अंतिम n लाइनों में अर्धविराम के साथ अल्पविराम को बदलना है। लेकिन केवल बहुत अंतिम एन लाइनों में।

मैं किसी भी लाइन को हटाना नहीं चाहता, मैं बस हर कॉमा को प्रत्येक फ़ाइल में अंतिम n लाइनों में एक अर्धविराम के साथ बदलना चाहता हूं।

Sed कमांड का उपयोग करके मैं इस कमांड के साथ अंतिम लाइन को बदलने में सक्षम हूं। जैसा कि यहाँ वर्णित है: मैं किसी फ़ाइल की अंतिम पंक्ति पर पाठ कैसे निकाल सकता हूँ?

लेकिन यह केवल मुझे बहुत अंतिम पंक्ति को संशोधित करने में सक्षम करता है, न कि अंतिम एन लाइनों की संख्या को।


1
बस शुरुआत sed '24,$s/,/:/g' filename24
वैलेंटाइन बजरमी

जवाबों:


13

अंतिम n लाइनों पर अर्धविराम के साथ अल्पविराम बदलने के लिए ed:

n=3
ed -s input <<< '$-'$((n-1))$',$s/,/;/g\nwq'

इसके अलावा विभाजन:

  • ed -s = चुपचाप चलाएं एड (अंत में लिखे गए बाइट्स की रिपोर्ट न करें)
  • '$-'फ़ाइल के अंत से = ( $) माइनस ...
  • $((n-1)) = n-1 लाइनें ...
  • ( $' ... '= शेल से बचाने के लिए कमांड के शेष भाग को उद्धृत करें)
  • ,$s/,/;/g= ... फ़ाइल के अंत तक ( ,$), अर्धविराम वाले सभी कॉमा को खोजें और बदलें।
  • \nwq = पिछली कमांड को समाप्त करें, फिर सहेजें और छोड़ें

अंतिम n लाइनों पर अर्धविराम के साथ अल्पविराम बदलने के लिए sed:

n=3
sed -i "$(( $(wc -l < input) - n + 1)),\$s/,/;/g" input

इसे तोड़ना:

  • -i फ़ाइल को "इन-प्लेस" संपादित करें
  • $(( ... )) = कुछ गणित करें:
  • $( wc -l < input) = फ़ाइल में लाइनों की संख्या प्राप्त करें
  • -n + 1 = पीछे की ओर n-1 रेखाएँ जाएँ
  • ,\$ फ़ाइल के अंत तक n-1 लाइनों से:
  • s/,/;/g = अर्धविराम के साथ अल्पविराम को बदलें।

जगह ले सकता है wc -l < inputके साथ wc -l input। कुछ नैनोसेकेंड्स से तेज होना चाहिए :)
गार्डेन

1
सिवाय इसके कि wc -l inputफ़ाइल नाम भी आउटपुट करता है; हम केवल लाइन गिनती चाहते हैं
जेफ स्कालर

एड के साथ पहली सलाह ठीक और सरल है।
sku2003

मैंने वास्तव में पूरी तरह से अलग पक्ष से सहायता प्राप्त करना समाप्त कर दिया। इस कोड के इस विषम टुकड़े के परिणामस्वरूप, यह चाल है लेकिन लंबी और अजीब है। मुझे लगता है कि यह कुछ अजीब चीजें हैं जिन्हें आप एक साथ एक समाधान के रूप में समाप्त कर सकते हैं। वैसे भी तुम्हारा अपने से छोटा, कम और जटिल है: यहाँ भी कोड काम किया है:
sku2003

cat input.file | sed 's /, /, \ n / g' | sed -n '1! G; h; $ p' | awk -vn = 2 'NR <= n {gsub (",", ";", $ 0)} {प्रिंट}' | sed -n '1! G; h; $ p' | sed '/ ^ \ s * $ / d'> output.file
sku2003

6

फ़ाइल के अंतिम 50 लाइनों में अर्धविराम के साथ हर अल्पविराम को बदलने के लिए टैक और सेड का उपयोग कर समाधान :

tac file.txt | sed '1,50s/,/;/g' | tac

5

GNU headऔर बॉर्न जैसी शेल के साथ:

n=20
{ head -n -"$n"; tr , ';'; } < file 1<> file

हम फ़ाइल को स्वयं ओवरराइट कर रहे हैं। यही कारण है कि एक बाइट-टू-बाइट लिप्यंतरण के लिए यहाँ ठीक है लेकिन जरूरी नहीं कि अगर संशोधन फ़ाइल का आकार परिवर्तित करने का अर्थ है (इस स्थिति में, आप बदलना चाहते चाहते हैं 1<> fileके साथ > other-file && mv other-file fileउदाहरण के लिए)।


1
यहाँ के लिए डॉक्स हैं1<> , जिनसे मैं अपरिचित था। इसके अलावा, मोरटाइलsponge से पाइपलाइनों के लिए एक अच्छा उपकरण है जहां आप अपने इनपुट को अधिलेखित करना चाहते हैं।
मीलों

1

मान लें कि हम 7शेल स्क्रिप्ट और GNU कार्यान्वयन के साथ निम्नलिखित अनुक्रम की अंतिम पंक्तियों को बदलना चाहते हैं sed:

$ seq 20
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

चरण 1 : निम्नलिखित की तरह अनुक्रम की अंतिम पंक्ति संख्या प्राप्त करने देता है। इस और उस पर एक नज़र डालें :

$ lastLine=`seq 20|sed -n '$='`

$ echo $lastLine 
20

चरण 2 : हम लाइनों की संख्या निर्धारित करते हैं (अनुक्रम के अंत में) जिसे हम संपादित करने का इरादा रखते हैं:

$ numberOfLines=7

$ echo $numberOfLines 
7

चरण 3 : निम्न की तरह, पिछले चर के आधार पर स्टार्ट लाइन की गणना करने देता है। इस पर एक नज़र डालें :

$ startLine=`expr $lastLine - $numberOfLines + 1`

$ echo $startLine 
14

चरण 4 : अब, हम अनुक्रम की आखिरी 7 पंक्तियों को निम्नलिखित की तरह कुछ और के साथ बदल सकते हैं। इस पर एक नज़र डालें :

$ seq 20|sed -e "$startLine,+$numberOfLines{s/[12]/WoW/}"
1
2
3
4
5
6
7
8
9
10
11
12
13
WoW4
WoW5
WoW6
WoW7
WoW8
WoW9
WoW0

चरण 4 sed मैन पेज के सेक्शन 4.4 का उपयोग कर रहा है जो कहता है:

'ADDR1,+N'
     Matches ADDR1 and the N lines following ADDR1.

चरण 4, यहां बताए अनुसार दोहरे उद्धरण चिह्नों का भी उपयोग कर रहा है


अगर हम गोहु के उत्तर का उपयोग इस तरह करते हैं तो 4 कदम अनावश्यक हैं :

$ seq 20 |tac|sed -e '1,7{s/[12]/WoW/}'|tac
1
2
3
4
5
6
7
8
9
10
11
12
13
WoW4
WoW5
WoW6
WoW7
WoW8
WoW9
WoW0

0

का प्रयोग करें tailऔर sed के लिए पाइप:

tail -n 20 file | sed 's/,/;/g'

यह अंतिम 20 लाइनों के लिए फ़ाइल पर काम करता है। यदि आप चाहते हैं कि आप फ़ाइल उपयोग के लिए सीधे कैग कर सकें:

tail -n 20 file | sed -i 's/,/;/g'

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