execução regex

4

Estou tentando substituir uma string em um arquivo:

$RELEASE     = '1234';

O espaço em branco entre RELEASE e o símbolo = pode ser espaços OU tabulações. As aspas em torno do número da versão podem ser simples ou duplas.

Atualmente, estou assumindo espaços e aspas simples no momento apenas para tentar fazer com que funcione:

sed 's/$RELEASE[[:space:]]*\=[[:space:]]*'\''[0-9]*'\'';/$RELEASE = '\''1234'\'';/g' config.ini > config.ini

Então, depois de muito trabalho, isso funciona. Mas somente se a string for espaços (como apostos a guias) e aspas simples como apostas a duplas. Aqui está o que eu tenho até agora para tentar lidar com as guias ...:

sed 's/$RELEASE([[:space:]]|\t)*\=([[:space:]]|\t)*'\''[0-9]*'\'';/$RELEASE = '\''1234'\'';/g' config.ini > config.ini

Acabei de ler que / t não é suportado na maioria das expressões regulares sed ... Isso é verdade? Existe uma substituição do tipo [[: tab:]]? (Eu tentei isso)

Qualquer ajuda seria apreciada.

    
por Chris 21.07.2014 / 15:23

2 respostas

2

Não tenho nenhum problema com [[:space:]] . Aqui está um pequeno exemplo muito bobo mostrando a substituição mista de espaços e guias:

$ echo -e 'A \t \t B' | sed 's/A[[:space:]]*B/WORKED/'
WORKED

Você também pode usar \s , que geralmente é preferível com grandes sed strings porque é muito mais curto:

$ echo -e 'A \t \t B' | sed 's/A\s*B/WORKED/'
WORKED

De qualquer forma, acho que o seu problema real é escapar dessas citações simples e problemáticas. Acho que a maneira mais fácil é sair da string de aspas simples e ter uma aspa simples entre aspas e, em seguida, (se necessário) voltar para a linha de aspas simples. O Bash irá concatenar automaticamente tudo isso para você.

$ echo 'This is a nice string and this is a single quote:'"'"' Nice?'
This is a nice string and this is a single quote:' Nice?

Assim, todo o espaço que salvamos com \s está prestes a ser destruído por essa situação de mega-cotação:

$ echo -e '$RELEASE  \t = '"'"'1234'"'"';' |\
  sed 's/$RELEASE\s*=\s*'"'"'[0-9]*'"'"'\;/REPLACEMENT/'

É claro que há um argumento de que (porque isso parece um script PHP) é possível supor que, se a linha começar com $RELEASE[\s=]+ , você poderá simplesmente substituir a linha inteira. Nem sempre é verdade, obviamente (o aplicativo inteiro pode ser uma linha horrorosa), mas torna sua pesquisa e substituição mais palatável:

sed 's/$RELEASE[\s=]*.*/REPLACEMENT/'

E sim, as regras gerais de uso de sed se aplicam. Não faça eco em um editor de fluxo (como sed ) e redirecione de volta para esse arquivo. Se funcionar, você poderá facilmente manipular o arquivo.

Use o argumento -i (funciona para sed ) ou canalize para um aplicativo como sponge (que é como uma saída atrasada):

sed -i '...' file
sed '...' file | sponge file
    
por 21.07.2014 / 16:24
0

Você pode agrupar a expressão e usar para apontar para o grupo. Por exemplo,

sed 's/^\($RELEASE.*=\).*/ '"'1234'"'/' config.ini
    
por 21.07.2014 / 16:48