Avec standard sed, vous ne verrez jamais de nouvelle ligne dans le texte lu à partir d'un fichier. En effet, sedlit ligne par ligne, il n'y a donc pas de nouvelle ligne à la fin du texte de la ligne courante dans sedl'espace de motif de. En d'autres termes, sedlit les données délimitées par des sauts de ligne et les délimiteurs ne font pas partie de ce qu'un sedscript voit.
Les expressions régulières peuvent être ancrées à la fin de la ligne en utilisant $(ou au début, en utilisant ^). L'ancrage d'une expression au début / à la fin d'une ligne la force à correspondre exactement là, et pas seulement n'importe où sur la ligne.
Si vous souhaitez remplacer quelque chose correspondant au motif [A-Za-z]*à la fin de la ligne par quelque chose, puis ancrer le modèle comme ceci:
[A-Za-z]*$
... le forcera à correspondre à la fin de la ligne et nulle part ailleurs.
Cependant, puisque ne[A-Za-z]*$ correspond également à rien (par exemple, la chaîne vide présente à la fin de chaque ligne), vous devez forcer la correspondance de quelque chose , par exemple en spécifiant
[A-Za-z][A-Za-z]*$
Ainsi, votre ligne de commande sed sera donc
$ sed 's/[A-Za-z][A-Za-z]*$/replace/' file.txt
Je n'ai pas utilisé le -Ecommutateur ici car il n'est pas nécessaire. Avec ça, vous auriez pu écrire
Bien que je sache comment le faire, vous obtiendrez un +1 juste pour utiliser le terme technique pour cela. :) C'est ce qu'on appelle l'ancrage - bon à savoir. Pour l'instant, j'ai toujours dû le paraphraser ... Une autre remarque sur le+ : vous pouvez l'utiliser même sans utiliser l'expression régulière étendue, n'oubliez pas de l'écrire comme \+. Cela sed -e 's/[A-Za-z]\+$/replace/' file.txtfonctionnera donc parfaitement même sans GNU sedinstallé. Et à ne pas oublier: ne l'utilisez pas -E, car GNU sedne le prend pas en charge .
erreur de syntaxe
1
@syntaxerror - Je pense que vous pouvez supprimer la dernière phrase ou au moins la mettre en gras comme gnu sedle soutient définitivement-E .
don_crissti
@don_crissti Eh bien, je pensais que vous étiez sur ce réseau depuis assez longtemps pour savoir qu'il n'y avait aucun moyen de déplier des parties d'un commentaire (à moins que vous ne le réécriviez entièrement). Alors permettez-moi de corriger: GNU sedpeut prendre en charge "silencieusement" -E, mais il n'est pas documenté dans la page de manuel (ni dans le manuel Texinfo (vérifié les deux)). Par conséquent, j'ai supposé qu'il n'était pas pris en charge (ce qui était une fausse hypothèse, après tout). Quoi qu'il en soit, vous avez raison, car au moins GNU sedne se plaindra pas si vous utilisez cette option.
erreur de syntaxe
@don_crissti Heureux que vous l'ayez fait! Donc, au moins, il a été confirmé qu'il sedfaudra une option particulière qui n'a pas encore été correctement documentée. Cela est toujours utile; si personne n'est au courant du manque de documentation, personne ne le corrigera jamais.
erreur de syntaxe
@syntaxerror, voir unix.stackexchange.com/a/310454/135943 . Bien sûr, si vous devez travailler avec d'anciens systèmes tels que RHEL 5, vous utiliserez une version GNU sed qui ne prend pas en charge -E.
Wildcard
3
sed "s/[a-zA-Z]*$/replace/" input.txt > result.txt
Ou, la manière inutile longue et complexe:
J'ai découvert que cela peut être fait, en utilisant toujours sed, avec l'aide de tr. Vous pouvez attribuer un autre caractère pour représenter la fin de la ligne. Un autre caractère temporaire doit être utilisé, dans ce cas "" ". Utilisons "~" pour représenter la fin de la ligne:
Je ne suis pas sûr de comprendre ... Pourquoi ne pas simplement ancrer en fin de ligne avec $? par exemples/[a-zA-Z]*$/replace/
don_crissti
1
2 points: 1) Vous feriez mieux d'utiliser \+au lieu de *puisque ce dernier autorise zéro lettre à la fin de la chaîne; 2) Vous pouvez utiliser une classe de caractères [[:alpha:]]. Donc:sed 's/[[:alpha:]]\+$/replace/' file
glenn jackman
@glennjackman À quoi sert la barre oblique inverse avant le plus? Cela ne correspondrait-il pas au caractère d'addition?
À partir de l'extrait de code (cassé) que vous avez publié, vous semblez également vouloir remplacer la nouvelle ligne. Dans ce cas, l'ancrage regex par lui-même ne peut pas vous aider. Voici une solution:
sed '/[[:alpha:]]\+$/{N;s/[[:alpha:]]\+\n/replace/}' your_file
En panne:
/[a-zA-Z]\+$/{} signifie appliquer tout ce qui se trouve à l'intérieur des boucles aux lignes qui correspondent à l'expression régulière.
À l'intérieur des curlies, Nsignifie «ajouter la ligne suivante au tampon actif» (ce qui sedappelle «l'espace modèle»)
Enfin, la s///déclaration est votre substitution requise. Cela fonctionne maintenant car l'espace de motif contient deux lignes successives et la nouvelle ligne en fait donc partie.
+
: vous pouvez l'utiliser même sans utiliser l'expression régulière étendue, n'oubliez pas de l'écrire comme\+
. Celased -e 's/[A-Za-z]\+$/replace/' file.txt
fonctionnera donc parfaitement même sans GNUsed
installé. Et à ne pas oublier: ne l'utilisez pas-E
, car GNUsed
ne le prend pas en charge .gnu sed
le soutient définitivement-E
.sed
peut prendre en charge "silencieusement"-E
, mais il n'est pas documenté dans la page de manuel (ni dans le manuel Texinfo (vérifié les deux)). Par conséquent, j'ai supposé qu'il n'était pas pris en charge (ce qui était une fausse hypothèse, après tout). Quoi qu'il en soit, vous avez raison, car au moins GNUsed
ne se plaindra pas si vous utilisez cette option.sed
faudra une option particulière qui n'a pas encore été correctement documentée. Cela est toujours utile; si personne n'est au courant du manque de documentation, personne ne le corrigera jamais.-E
.Ou, la manière inutile longue et complexe:
la source
$
? par exemples/[a-zA-Z]*$/replace/
\+
au lieu de*
puisque ce dernier autorise zéro lettre à la fin de la chaîne; 2) Vous pouvez utiliser une classe de caractères[[:alpha:]]
. Donc:sed 's/[[:alpha:]]\+$/replace/' file
-r
option utilise cette syntaxe d'expression régulière .À partir de l'extrait de code (cassé) que vous avez publié, vous semblez également vouloir remplacer la nouvelle ligne. Dans ce cas, l'ancrage regex par lui-même ne peut pas vous aider. Voici une solution:
En panne:
/[a-zA-Z]\+$/{}
signifie appliquer tout ce qui se trouve à l'intérieur des boucles aux lignes qui correspondent à l'expression régulière.N
signifie «ajouter la ligne suivante au tampon actif» (ce quised
appelle «l'espace modèle»)s///
déclaration est votre substitution requise. Cela fonctionne maintenant car l'espace de motif contient deux lignes successives et la nouvelle ligne en fait donc partie.la source
Pour trouver la fin de la ligne, utilisez simplement le signe $ :
Sans ancrage de fin de ligne:
Sans ancrage de fin de ligne:
la source