SED: comment décommenter une ligne contenant une chaîne spécifique? (édition en ligne)

Les lignes du fichier:

-A INPUT -m state --state NEW -m tcp -p tcp --dport 2000 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2001 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2002 -j ACCEPT

Pour commenter disons la ligne qui contient

2001

Je peux simplement exécuter cette commande SED:

sed -i '/ 2001 /s/^/#/' file

Mais maintenant, comment puis-je revenir en arrière ?

Comme dans décommenter cette même ligne ?

J'ai essayé

sed -i '/ 2001 /s/^//' file

Cela ne fonctionne pas.

33
demandé sur Avinash Raj 2014-07-22 17:54:05

3 réponses

Essayez cette commande sed,

sed -i '/^#.* 2001 /s/^#//' file
36
répondu Avinash Raj 2014-07-22 14:05:37

Oui, pour commenter une ligne contenant une chaîne spécifique avec sed, faites simplement:

sed -i '/<pattern>/s/^/#/g' file

Et pour le décommenter:

sed -i '/<pattern>/s/^#//g' file

Dans votre cas:

sed -i '/2001/s/^/#/g' file    (to comment out)
sed -i '/2001/s/^#//g' file    (to uncomment)

L'Option "g" à la fin signifie changement global. Si vous voulez changer une seule instance de pattern, ignorez simplement ceci.

51
répondu JNLK 2014-12-08 09:37:36

Pour compléter la réponse utile de @Avinash Raj avec un plus générique, solution conforme à POSIX.

  • Bascule commentant les lignes qui correspondent à un déterminable string, ce qui doit se produire comme un mot séparé n'importe où sur la ligne.
  • le caractère de commentaire (chaîne) est également spécifiable .

Notez que la solution est basée sur awk , car une solution robuste la solution portable avec sed est pratiquement impossible en raison des limitations de POSIX' Basic expressions régulières.

awk -v commentId='#' -v word='2001' '
  $0 ~ "(^|[[:punct:][:space:]])" word "($|[[:punct:][:space:]])" { 
    if (match($0, "^[[:space:]]*" commentId))
      $0 = substr($0, RSTART + RLENGTH)
    else
      $0 = commentId $0
  } 
  { print }
  ' file > tmpfile.$$ && mv tmpfile.$$ file
  • (^|[[:punct:][:space:]]) et ($|[[:punct:][:space:]]) sont les équivalents POSIX des expressions rationnelles étendues des assertions de limites de mots \< et \> connues d'autres dialectes regex.
  • les espaces après le caractère de commentaire est conservé, mais pas avant.
  • lors de l'ajout du caractère de commentaire à une ligne, il est directement ajouté, sans des espaces.
  • ainsi, si vous basculez uniquement les commentaires avec Cette solution , tous les espaces sont conservés.
  • POSIX awk n'offre pas de mise à jour sur place (POSIX sed non plus, incidemment), donc la sortie est d'abord capturée dans un fichier temporaire et ce fichier remplace ensuite l'original en cas de succès.
3
répondu mklement0 2017-05-23 12:10:07