Substituir string em string, mas não quando estiver em algum lugar entre colchetes duplos

0

Eu tenho uma longa string do campo mysql contendo os dados de uma página mediawiki. Eu tenho que substituir uma string nessa página mediawiki, mas não quando a string está no link mediawiki. O link mediawiki é identificado por um colchete duplo.

por exemplo. Substitua "Termo" em "Aqui está o Termo que deve ser substituído" mas não substitua "Aqui [[é o Termo que]] não deve ser substituído"

A solução pode ser mysql ou sed, awk ou qualquer outra coisa. Por favor ajude. Obrigado.

    
por BSDGuy 20.02.2014 / 10:36

3 respostas

0

Eu prefiro abordar esse tipo de coisa usando uma ferramenta que pode dividir a string usando um delimitador de vários caracteres. Você pode usar seu "padrão excluído" como delimitador e fazer substituições em elementos que não são o delimitador. Porque eu gosto de perl, eu vou fazer um perl one-liner aqui. :)

Primeiro, porque "perl" não foi uma das suas soluções sugeridas, acho que o perl não é algo em que você é strong. Então, vou começar com algumas coisas que você precisa saber sobre o perl para entender como isso funciona:

Se você colocar parens em torno do padrão de divisão na função perl split , o separador será retido como um elemento adicional na matriz retornada por split . Usar \[\[.*?\]\] nos fornece a menor string contida entre [[ e ]] , portanto, na matriz retornada, podemos selecionar elementos que não começam com [[ e fazem a substituição apenas nesses elementos. Com foreach e map, $ _ será uma referência (ponteiro) para o elemento da matriz, portanto, as alterações em $ _ alteram os elementos da matriz. Assim, depois de alterar a matriz, podemos unir os elementos potencialmente modificados e os delimitadores - ainda na ordem correta - de volta junto com os caracteres vazios. Além disso, gosto de usar unless() , enquanto outras pessoas preferem if(!) (mesmo com minha preferência de usar q{} em vez de '' , porque '' parece com " e "" parece com '''' ;)). Isso não é golfe de código, e acho que é mais legível do meu jeito. :)

Ah, e caso isso também seja novo: perl -lne - o -l lida de forma transparente com novas linhas, o que eu acho que realmente não nos importamos aqui, mas é um hábito. O -n coloca o código dentro de um while(<>){} .

Com tudo isso dito, aqui está um exemplo funcional (sem sentido) substituindo cada não link "a" por "pie":

danny@host [/home/danny]
$ cat testfile
a b c d [[a]] b c d [[ moo a moo]] a
I like to eat [[meat]] on a plate
danny@host [/home/danny]
$ perl -nle'@l=split(/(\[\[.*?\]\])/); foreach (@l){s/a/pie/g unless(/^\[\[/)};
print join(q{}, @l)' testfile
pie b c d [[a]] b c d [[ moo a moo]] pie
I like to epiet [[meat]] on pie plpiete
    
por 20.02.2014 / 16:48
0

Use o replace.py do pywibot .

replace.py -exceptinside:link -regex "Term" "New term"

As outras respostas são erradas (não confiáveis) e desnecessariamente complicadas.

    
por 05.04.2015 / 23:14
-1

Aqui está um código que deve funcionar para você. Testado no bash no AIX:

#!/usr/bin/bash
#filename: test2.sh
searchandreplace() {
   thisline=$1
   echo $thisline | awk '
BEGIN { FS= "[" }
/\[/ {sub(/Term/,"foobar");print}
!/\[/ {print}
'
}

infile=test.in
cat $infile | while read line
do
   searchandreplace "$line"
done

Aqui está test.in:

"Here is the Term that has to be replaced" "Here [[is the Term that]] must not be replaced"
third line

Exemplo quando executado:

    
por 20.02.2014 / 17:01