एकाधिक पाठ फ़ाइलों की 5 वीं पंक्ति पर स्ट्रिंग को कैसे बदलें?


22

मैं एक सिंगल टर्मिनल कमांड का उपयोग करके "गुड मॉर्निंग" स्ट्रिंग के साथ कई टेक्स्ट फाइलों की 5 वीं पंक्ति ( file1.txt, file2.txt, file3.txt, file4.txt ) को बदलना चाहता हूं ।

सभी पाठ फ़ाइलें मेरे पर स्थित हैं ~/Desktop

नोट: मेरे डेस्कटॉप में 6 .txt फाइलें हैं। मैं उपर्युक्त 4 टेक्स्ट फाइलों में बदलाव को लागू करना चाहता हूं।

जवाबों:


40

यहाँ कुछ दृष्टिकोण हैं। मैं ब्रेस विस्तार ( file{1..4}.txt) का उपयोग कर रहा हूं जिसका अर्थ हैfile1.txt file2.txt file3.txt file4.txt

  1. पर्ल

    perl -i -pe 's/.*/ Good Morning / if $.==5' file{1..4}.txt

    स्पष्टीकरण:

    • -i: perlमूल फ़ाइल को बदलते हुए फ़ाइलों को जगह में संपादित करने का कारण बनता है।

      यदि -iफ़ाइल एक्सटेंशन प्रत्यय के साथ पालन किया जाता है, तो संशोधित की गई प्रत्येक फ़ाइल के लिए एक बैकअप बनाया जाता है। Ex: -i.bakक्रिएट करता है file1.txt.bakयदि file1.txtनिष्पादन के दौरान इसे संशोधित किया जाता है।

    • -p: का मतलब है कि लाइन द्वारा इनपुट फ़ाइल लाइन पढ़ें, स्क्रिप्ट लागू करें और इसे प्रिंट करें।

    • -e: आपको कमांड लाइन से एक स्क्रिप्ट पास करने की अनुमति देता है।

    • s/.*/ Good Morning /: यह पाठ को वर्तमान पंक्ति ( .*) में सुप्रभात के साथ बदल देगा ।

    • $.एक विशेष पर्ल वैरिएबल है जो इनपुट फ़ाइल की वर्तमान पंक्ति संख्या रखता है। तो, का s/foo/bar/ if $.==5मतलब है केवल 5 वीं पंक्ति के fooसाथ बदलें bar

  2. sed

    sed -i '5s/.*/ Good Morning /' file{1..4}.txt

    स्पष्टीकरण:

    • -i: जैसे perl, फ़ाइल को जगह में संपादित करें।

    डिफ़ॉल्ट रूप से, sedइनपुट फ़ाइल की प्रत्येक पंक्ति को प्रिंट करता है। 5s/pattern/replacement/5 वीं लाइन पर प्रतिस्थापन के साथ साधन स्थानापन्न पैटर्न।

  3. awk

    for f in file{1..4}.txt; do 
        awk 'NR==5{$0=" Good Morning "}1;' "$f" > foobar && mv foobar "$f"; 
    done

    स्पष्टीकरण:

    awkविकल्प के समतुल्य नहीं है, -iजिसका अर्थ है कि हमें एक अस्थायी फ़ाइल ( foobar) बनाने की आवश्यकता है जिसे मूल नाम को अधिलेखित करने के लिए नाम दिया गया है। बैश लूप for f in file{1..4}.txt; do ... ; doneबस file{1..4}.txtवर्तमान फ़ाइल नाम को सहेजते हुए, प्रत्येक के माध्यम से जाता है $f। में awk, NRवर्तमान लाइन नंबर है और वर्तमान लाइन $0की सामग्री है। इसलिए, स्क्रिप्ट $0केवल 5 वीं पंक्ति पर "गुड मॉर्निंग" के साथ लाइन ( ) को प्रतिस्थापित करेगी । 1;है awk"लाइन प्रिंट के लिए"।

    ¹ नए संस्करणों devnull अपने में पता चला है के रूप में इस सवाल का जवाब

  4. coreutils

    for f in file{1..4}.txt; do 
        (head -4 "$f"; echo " Good Morning "; tail -n +6 "$f") > foobar && 
        mv foobar "$f"; 
    done 

    स्पष्टीकरण:

    लूप को पिछले भाग में समझाया गया है।

    • head -4: पहले 4 लाइनों को प्रिंट करें

    • echo " Good Morning ": "गुड मॉर्निंग" प्रिंट करें

    • tail -n +6: छठी पंक्ति से फ़ाइल के अंत तक सब कुछ प्रिंट करें

    ( )उन तीन आदेशों के आसपास के कोष्ठक आपको तीनों (इसलिए, पहली 4 पंक्तियों, फिर "सुप्रभात", फिर बाकी पंक्तियों) के आउटपुट को कैप्चर करने की अनुमति देते हैं और उन्हें एक फ़ाइल पर पुनर्निर्देशित करते हैं।


23

आप उपयोग कर सकते हैं sed:

sed '5s/^/Good morning /' file

Good morningएक फ़ाइल की पांचवीं पंक्ति पर संलग्न होगा ।

यदि आप इसके बजाय लाइन 5 पर सामग्री बदलना चाहते हैं, तो कहें:

sed '5s/.*/Good morning/' file

यदि आप फ़ाइल में किए गए परिवर्तनों को इन-प्लेस में सहेजना चाहते हैं, तो -iविकल्प का उपयोग करें :

sed -i '5s/.*/Good morning/' file

sedएक समय में एक से अधिक फ़ाइल संभाल सकता है। आप केवल कमांड के अंत में अधिक फ़ाइल नाम जोड़ सकते हैं। आप विशेष फ़ाइलों से मिलान करने के लिए बैश विस्तार का भी उपयोग कर सकते हैं:

# manually specified
sed -i '5s/.*/Good morning/' file1.txt file2.txt file3.txt file4.txt

# wildcard: all files on the desktop
sed -i '5s/.*/Good morning/' ~/Desktop/*

# brace expansion: file1.txt, file2.txt, file3.txt, file4.txt
sed -i '5s/.*/Good morning/' file{1..4}.txt

आप यहाँ ब्रेस विस्तार के बारे में अधिक पढ़ सकते हैं


GNU awk संस्करण 4.1.0 और उच्चतर एक एक्सटेंशन के साथ आते हैं जो इन-प्लेस संपादन सक्षम करते हैं। तो आप कह सकते हैं:

gawk -i inplace 'NR==5{$0="Good morning"}7' file

फ़ाइल में लाइन # 5 को बदलने के लिए Good morning!


2

मैंने अजगर के समाधान को यहाँ नहीं देखा, इसलिए यह है:

import sys
import os
def open_and_replace(filename):

    with open(filename) as read_file:
        temp = open("/tmp/temp.txt","w")
        for index,line in enumerate(read_file,1):
            if  index == 5:
                temp.write("NEW STRING\n")
            else:
                temp.write(line.strip() + "\n")
        temp.close()
    os.rename("/tmp/temp.txt",filename)

for file_name in sys.argv[1:]:
    open_and_replace(file_name)

मूल विचार यह है कि कमांड-लाइन पर दिए गए प्रत्येक फ़ाइल को तर्क के रूप में, हम एक अस्थायी फ़ाइल लिखते हैं और प्रत्येक फ़ाइल को मूल फ़ाइल में एन्यूमरेट करते हैं। यदि लाइन का इंडेक्स 5 है, तो हम आउट लाइन लिखते हैं जो अलग है। बाकी बस पुरानी फ़ाइल को अस्थायी फ़ाइल के साथ बदल रहा है डेमो:

$> ls
file1.txt  file2.txt  file3.txt
$> cat file1.txt                                                               
line 1
line 2
line 3
line 4
GOOD MORNING
line 6
$> python ~/replace_5th_line.py file1.txt file2.txt  file3.txt                 
$> cat file1.txt                                                               
line 1
line 2
line 3
line 4
NEW STRING
line 6
$> cat file2.txt                                                               
line 1
line 2
line 3
line 4
NEW STRING
line 6

सूची बोध के साथ ही इसे प्राप्त किया जा सकता है। नीचे एक ही लिपि का एक लाइनर है:

cat /etc/passwd | python -c 'import sys; print "\n".join(["CUSTOM"  if index == 5 else line.strip() for index,line in enumerate(sys.stdin,1)])'

या बिना cat

python -c 'import sys; print "\n".join(["CUSTOM"  if index == 5 else line.strip() for index,line in enumerate(sys.stdin,1)])' < /etc/passwd

जो कुछ बचा है, वह केवल संपादित की गई सामग्री के आउटपुट को किसी अन्य फ़ाइल में पुनर्निर्देशित करना है > output.txt


1

आप पूर्व मोड में विम का उपयोग कर सकते हैं:

for b in 1 2 3 4
do
  ex -sc '5c|Good Morning' -cx file"$b".txt
done
  1. 5 5 वीं पंक्ति का चयन करें

  2. c पाठ बदलें

  3. x यदि परिवर्तन किए गए हैं तो वे लिखें और छोड़ दें


0

निम्नलिखित एक बैश स्क्रिप्ट है जो इस उत्तर में सुझाई गई पर्ल प्रक्रिया को लपेटता है

उदाहरण:

/ Tmp / यह

console:
  enabled:false

फिर निम्नलिखित को चलाएँ:

$ search_and_replace_on_line_of_file.sh false true 2 /tmp/it

और फ़ाइल में अब शामिल है

/ Tmp / यह

console:
  enabled:true

search_and_replace_on_line_of_file.sh

function show_help()
{
  IT=$(CAT <<EOF

  usage: SEARCH REPLACE LINE_NUM FILE

  e.g. 

  false true 52 /tmp/it  -> replaces false with true on line 52 of file /tmp/it

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$4" ]
then
  show_help
fi

SEARCH_FOR=$1
REPLACE_WITH=$2
LINE_NO=$3
FILE_NAME=$4
perl -i -pe "s/$SEARCH_FOR/$REPLACE_WITH/ if $.==$LINE_NO" $FILE_NAME 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.