Gostaria de usar sed
ou perl
substituir todas as ocorrências de uma palavra que não tenha uma determinada palavra na frente.
Por exemplo, eu tenho um arquivo de texto que contém a trama de um filme e desejo substituir todas as ocorrências do sobrenome de um personagem pelo primeiro nome, mas apenas se o primeiro nome não aparecer imediatamente antes do sobrenome.
O texto de exemplo pode ficar assim:
John Smith and Jane Johnson talk about Smith's car.
Eu quero que fique assim:
John Smith and Jane Johnson talk about John's car.
Se eu apenas fizer sed 's/Smith/John/' file
, então eu teria:
John John and Jane Johnson talk about John's car.
O primeiro nome que vem antes do sobrenome sempre será o mesmo. Eu não tenho que lidar com John Smith
e Frank Smith
. Eu só preciso de uma maneira de combinar Smith
que não tem John
precedente.
sed
regular-expression
perl
jonescb
fonte
fonte
Respostas:
Seria fácil com qualquer idioma em que as expressões regulares sejam capazes de olhar para trás. Obviamente, Perl é o primeiro da lista:
O ponto fraco é ter mais de um caractere que não seja uma palavra entre "John" e "Smith". Infelizmente um quantificador como
+
para\W
elevaria “comprimento variável não lookbehind implementado” erro.fonte
EDIT .. re seu comentário .. Aqui está um novo script que não se preocupa com (por exemplo) William Smith. Oculta temporariamente os padrões que mantém como Smith (inalterados).
Se você está preocupado com o Sr. Sra ... então isso funciona.
Você pode atender a William adicionando seu nome à lista ou , por exemplo.
sed -r 's/\<(William|John|...
Este é o script original
fonte
O () capturará o não nome antes de um sobrenome, para que eles sejam retrocedidos na substituição.
Editar
@ manatwork, gilles
Você está certo. E se
Isso parece fazer o truque.
fonte
[^John]
corresponde a um caráter que deve ser um dosJ
,o
,h
oun
. Duvido que seja isso que você pretendia. Não há construto de negação em expressões regulares (Perl tem(?!…)
e(?<!…)
, mas se você pensar nisso como uma negação, provavelmente não fará o que você espera).sed
sem ele faz com que a lógica sed inchada ...temp1
quase sempre será boa, mas! cuidado com o ônibus. Para atenuar essa possibilidade, acredito que é melhor usar caracteres que (quase) nunca ocorrem em arquivos de texto em script latino, por exemplo, valor hexadecimal \ x01 \ x02, ou combinações deles, ou talvez \ xe188b4 localidade UTF-8 (ሴ - SYLLABLE ETIÓPICO VER) .. por exemplo.echo -e 'Z' |sed 's/./\xe1\x88\xb4/'
=>ሴ
Quando localidade é UTF-8 ..