Je voudrais utiliser sed
ou perl
remplacer toutes les occurrences d'un mot qui n'a pas un certain mot devant lui.
Par exemple, j'ai un fichier texte qui contient une intrigue d'un film et je veux remplacer toutes les occurrences du nom de famille d'un personnage par leur prénom, mais seulement si leur prénom ne vient pas immédiatement avant leur nom de famille.
Un exemple de texte pourrait ressembler à ceci:
John Smith and Jane Johnson talk about Smith's car.
Je veux que ça ressemble à ceci:
John Smith and Jane Johnson talk about John's car.
Si je le fais sed 's/Smith/John/' file
, j'aurais:
John John and Jane Johnson talk about John's car.
Le prénom qui précède le nom de famille sera toujours le même. Je n'ai pas à gérer John Smith
et Frank Smith
. J'ai juste besoin d'un moyen de faire correspondre Smith
celui qui ne l'a pas John
précédé.
sed
regular-expression
perl
jonescb
la source
la source
Réponses:
Ce serait facile avec n'importe quelle langue où les expressions régulières sont capables de regarder derrière. Bien sûr, Perl est le premier sur la liste:
Le point faible est d'avoir plus d'un caractère non-mot entre «John» et «Smith». Malheureusement, un quantificateur tel que
+
for\W
soulèverait l'erreur «Lookbehind de longueur variable non implémenté».la source
EDIT .. re votre commentaire .. Voici un nouveau script qui ne se préoccupe pas (par exemple.) De William Smith. Il obscurcit temporairement les motifs qu'il garde comme Smith (inchangé).
Si vous êtes préoccupé par M. Mr Mme ... alors cela fonctionne.
Vous pouvez répondre à William en ajoutant son nom à la liste ou , par exemple.
sed -r 's/\<(William|John|...
Ceci est le script d'origine
la source
Le () capturera le non-prénom avant un nom de famille, donc ils sont rétro-réfutés dans le remplacement.
Éditer
@ manatwork, gilles
Vous avez raison. Que diriez-vous
Cela semble faire l'affaire.
la source
[^John]
correspond à un caractère qui doit être l' unJ
,o
,h
oun
. Je doute que c'est ce que vous vouliez. Il n'y a pas de construction de négation dans les expressions régulières (Perl a(?!…)
et(?<!…)
, mais si vous le considérez comme une négation, il ne fera probablement pas ce que vous attendez).sed
sans elle rend la logique sédative gonflée ... cetemp1
sera presque toujours bien, mais! attention à ce bus. Pour atténuer cette possibilité, je pense qu'il est préférable d'utiliser des caractères qui (presque) ne se produisent jamais dans les fichiers texte en Latin-Script, par exemple la valeur Hex \ x01 \ x02, ou des combinaisons d'entre eux, ou peut-être \ xe188b4 locale UTF-8 (ሴ - ETHIOPIC SYLLABLE SEE) .. ex.echo -e 'Z' |sed 's/./\xe1\x88\xb4/'
=>ሴ
lorsque les paramètres régionaux sont UTF-8 ..