Como substituir uma linha por várias linhas em um arquivo, programaticamente?

2

Eu tenho este arquivo de configuração que quero editar programaticamente. Eu sempre uso sed para fazer pequenas alterações, mas agora preciso substituir 1 linha por várias linhas, algo assim:

some code
# maintenance placeholder
more code

Altere para isso

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

Como posso fazer isso?

    
por ChocoDeveloper 01.02.2013 / 23:57

3 respostas

2

Eu fui em frente e criei um pequeno utilitário para você em C ++, espero que seja útil para você. Simplesmente compile e aproveite.

#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;
}

Compilado com:

g++ -o replacer replacer.cpp

Uso da amostra:

input.txt:

1
2
3
4
5

search.txt

3

replace.txt

Three

Comando

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

output.txt

1
2
Three
4
5

Se você tiver outras dúvidas, pergunte. Eu espero que ele realize o que você queria que ele fizesse. (Ele também aceita stdin e outputs para stdout se você omitir -i e -o) É claro que novas linhas, aspas, etc. não causarão nenhum problema, porque elas estão em arquivos separados.

    
por 03.02.2013 / 19:37
2

Se você tiver perl, tente usar:

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

isto irá substituir 'oldtext' por 'newtext' no arquivo.txt e criará um backup do arquivo chamado file.txt.bak

    
por 05.02.2013 / 18:53
1

Caso a resposta do @ u8sand (comentário) não esteja clara o suficiente para você, você pode fazer o que descreve por

sed '/# maintenance placeholder/c\
maintenance line 1\
maintenance line 2\
'

Você pode fazer a mesma coisa nos comandos s :

sed 's/SuperUser/Super\
User/'

Talvez, como sugere u8sand, haja versões de sed em que as barras invertidas não são necessárias.

    
por 02.02.2013 / 00:21