प्रोग्राम में प्रोग्राम में एक लाइन को कई लाइनों के लिए कैसे बदला जाए?


2

मेरे पास यह कॉन्फ़िग फ़ाइल है जिसे मैं प्रोग्रामेटिक रूप से संपादित करना चाहता हूं। मैं हमेशा sedछोटे बदलाव करने के लिए उपयोग करता हूं , लेकिन अब मुझे कई लाइनों के लिए 1 लाइन बदलने की जरूरत है, कुछ इस तरह से:

some code
# maintenance placeholder
more code

इसे इसमें बदलें

some code
maintenance line 1
maintenance line 2
maintenance line 2
more code

मैं उसे कैसे कर सकता हूँ?


sed कई पंक्तियों का समर्थन करता है, (आपको एक \ n या कुछ भी नहीं चाहिए जो आप केवल टाइप करें (बिना उद्धरणों को बंद किए) दर्ज करें) यदि यह आपके प्रश्न का उत्तर नहीं देता है तो मैं अनिश्चित हूं कि यह आप क्या चाहते हैं।
u8sand

@ u8sand क्या होगा यदि कोड में भी उद्धरण हों? हर चीज से बचना एक काम है।
चोकोडेवेल्टर 23

वास्तव में यह होगा, आप किस प्रोग्रामिंग या स्क्रिप्टिंग भाषा का उपयोग करने की उम्मीद कर रहे थे? मैं एक उपयोगिता की सिफारिश करता हूं जो कि अलग-अलग फाइलों को स्वीकार करता है, इनपुट टेक्स्ट, जिसे आप ढूंढ रहे हैं और इसके साथ क्या बदलना है। उदाहरण के लिए: cat file.old.conf | replacer -s search.txt -r replace.txt> file.new.conf
u8sand

जवाबों:


2

मैंने आगे बढ़कर C ++ में आपके लिए थोड़ी उपयोगिता बनाई, मुझे आशा है कि यह आपके लिए उपयोगी है। बस इसे संकलित करें और आनंद लें।

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(int argc,char *argv[])
{
    fstream i,
                    s,
                    r,
                    o;
    string s_str,
                 r_str,
                 buf;
    int n;
    char ch,
             s_in = 1,
             s_out = 1;

    for(int n = 1; n < argc; n += 2)
    {
        if(argv[n][0] == '-')
        {
            switch(argv[n][1])
            {
                case 'i':
                    i.open(argv[n+1], fstream::in);
                    s_in = 0;
                    break;
                case 's':
                    s.open(argv[n+1], fstream::in);
                    break;
                case 'r':
                    r.open(argv[n+1], fstream::in);
                    break;
                case 'o':
                    o.open(argv[n+1], fstream::out);
                    s_out = 0;
                    break;
                default:
                    cerr << "Usage: helper [-i input_file] <-s search_file> <-r replace_file> [-o output_file]";
                    return 0;
            }
        }
    }
    if(!s_in && !i.is_open())
    {
        cerr << "Input could not be opened.";
        return -1;
    }
    if(!s.is_open())
    {
        cerr << "Search could not be opened.";
        return -1;  
    }
    if(!r.is_open())
    {
        cerr << "Replace could not be opened.";
        return -1;
    }
    if(!s_out && !o.is_open())
    {
        cerr << "Output could not be opened.";
        return -1;
    }

    /* get s and r in memory */
    while((ch = s.get()) != EOF)
        s_str += ch;
    s.close();
    while((ch = r.get()) != EOF)
        r_str += ch;
    r.close();

    buf = "";
    while((s_in ? (ch = cin.get()) : (ch = i.get())) != EOF)
    {
        buf += ch;
        for(n = 0; n < buf.length(); n++)
            if(buf.at(n) != s_str.at(n))
            {
                s_out ? (cout << buf) : (o << buf);
                buf = "";
                break;
            }
        if(n == s_str.length())
        {
            s_out ? (cout << r_str) : (o << r_str);
            buf = "";
        }
    }
    s_out ? (cout << buf) : (o << buf);

    if(!s_in)
        i.close();
    if(!s_out)
        o.close();

    return 0;
}

इसके साथ संकलित:

g++ -o replacer replacer.cpp

नमूना उपयोग:

input.txt:

1
2
3
4
5

search.txt

3

replace.txt

Three

आदेश

./replacer -i input.txt -s search.txt -r replace.txt -o output.txt

output.txt

1
2
Three
4
5

यदि आपके कोई और प्रश्न हैं, तो कृपया पूछें। मुझे आशा है कि यह पूरा करता है कि आप क्या करना चाहते थे। (यह स्टडआउट को भी स्वीकार करता है, और यदि आप ommit -i और -o) को स्टैडआउट करना चाहते हैं, तो निश्चित रूप से नई कथनों, उद्धरणों, ect .. के कारण कोई समस्या नहीं होगी क्योंकि वे अलग-अलग फ़ाइलों में हैं।


2

यदि आपके पास पर्ल है, तो प्रयोग करके देखें:

perl -pi.bak -e's / oldtext / newtext / 'file.txt

यह 'oldtext' को 'newtext' के साथ file.txt में बदल देगा, और file.txt.ak नामक फाइल का बैकअप बना देगा।


1

यदि आप के लिए पर्याप्त नहीं है, तो आप @ u8sand का उत्तर (टिप्पणी) स्पष्ट नहीं कर सकते हैं

sed '/ # रखरखाव प्लेसहोल्डर / c \
रखरखाव लाइन 1 \
रखरखाव लाइन 2 \
'

आप sकमांड में एक ही काम कर सकते हैं :

sed 's / SuperUser / Super \
उपयोगकर्ता / '

शायद, जैसा कि u8sand बताता है, ऐसे संस्करण हैं sedजहां बैकस्लैश की आवश्यकता नहीं है।

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