Sed - remplacer un personnage dans une ligne assortie en place?


21

Dans un fichier contenant des lignes comme celle-ci:

# lorem ipsum blah variable

Je voudrais supprimer le caractère #(commentaire) dans la même ligne qui contient une chaîne spécifique, en place. Est-ce sedbon pour ça?

J'ai du mal à faire fonctionner ce conditionnel. J'ai une façon "maladroite" de faire cela; Je peux trouver le numéro de ligne correspondant avec awkou sedpuis utiliser ce numéro dans une sedcommande distincte , mais je pense que cela peut être fait de bien meilleure façon.

Réponses:


37

Utilisez la chaîne que vous recherchez comme sélecteur pour les lignes à opérer:

sed '/ipsum/s/#//g'

/ipsum/sélectionne les lignes contenant "ipsum" et uniquement sur ces lignes les commandes qui suivent sont exécutées. Vous pouvez utiliser des accolades pour exécuter plus de commandes

/ipsum/{s/#//g;s/@/-at-/g;}

4
Je suis d'accord; c'est la meilleure réponse (mais pas la seule). Commentaires: (1) 's/#//g'supprimera tous les #caractères de la ligne. Si ce n'est pas ce que vous voulez, supprimez le g(qui signifie «global»). (2) Pour éditer un fichier en place (comme demandé dans la question), utilisez sed -i.
G-Man dit `` Réintègre Monica '' le

2
(3) Dans le cas de situations réelles, si vous souhaitez annuler le commentaire d'une ligne, vous pouvez utiliser sed -i '/ipsum/s/#[[:space:]]*//'pour supprimer les espaces et les tabulations immédiatement après le #. (4) Vous pouvez également envisager de vérifier que le #est le premier caractère non vide de la ligne. La commande actuelle supprimerait le #de la ligne prompt "Enter # of ipsums:".
G-Man dit `` Réintègre Monica '' le

1
@ G-Man - excellent ajout! À votre 2e pt (espace de tête), qu'en est-il de: sed -i '/ipsum/s/^#[[:space:]]*//'?! ( ^signifie début de ligne, $pour fin de ligne) - au moins dans gnu sed ...
Jeremy Davis

1
@ JeremyDavis: Oui, vous pouvez ancrer l'expression régulière au début de la ligne ^, mais ce serait faux. Je commente souvent le code indenté en mettant #immédiatement le code avant, donc le #est indenté. Je doute que je suis la seule personne à le faire.
G-Man dit `` Réintègre Monica ''

1
@ G-Man - ah oui, bien sûr! Merci, je n'y avais pas pensé. Donc , vous voulez également vérifier des espaces entre ^et #, donc quelque chose comme ceci: /ipsum/{/^[[:space:]]*#/s/#[[:space:]]*//}. Bien que même dans ce cas, en fonction de l'endroit où il se #trouve, cela puisse toujours causer des problèmes (par exemple dans les langues qui utilisent l'indentation / séparation des espaces blancs).
Jeremy Davis

7
$ cat input.txt
# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
# lorem ipsum blue variable

ensuite:

$ sed 's|# \(.*blue.*\)|\1|' input.txt

donne:

# lorem ipsum blah variable
# lorem ipsum blat variable
# lorem ipsum blow variable
# lorem ipsum blip variable
lorem ipsum blue variable

Cela fonctionne comme suit:

Le sdit sedqu'il doit remplacer ce que trouve l'expression régulière.

Le modèle est # \(.*blue.*\)le suivant: trouver un hachage suivi d'un espace. Le crochet ( \() démarre le regroupement. .*blue.*est le mot blueavec quoi que ce soit avant et après. Le crochet suivant ( \)) ferme le regroupement.

Le remplacement est \1une référence arrière au contenu du premier support de regroupement.


3

Vous pouvez utiliser Vim en mode Ex:

ex -sc '/ipsum/s/#//|x' file
  1. s remplacer

  2. x sauver et fermer


C'est plutôt cool. Je n'en savais rien! TBH, je ne suis pas sûr que ce soit la meilleure réponse à cette question (IMO la principale réponse sed est celle) mais c'est quand même très cool! Merci d'avoir posté.
Jeremy Davis
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.