web-dev-qa-db-fra.com

Utilisation de sed pour supprimer à la fois un crochet carré d'ouverture et de fermeture autour d'une chaîne

J'exécute cette commande dans un shell bash sur Ubuntu 12.04.1 LTS. J'essaie de supprimer à la fois le [ et ] les caractères d'un seul coup, c'est-à-dire sans avoir besoin de siffler une seconde fois.

Je sais que les crochets ont une signification particulière dans une expression régulière, je les échappe donc en ajoutant une barre oblique inverse. Le résultat que j'attendais est juste la chaîne 123 mais les crochets restent et j'aimerais savoir pourquoi!

~$ echo '[123]' | sed 's/[\[\]]//'
[123]
23
Xhantar

C'est facile, si vous suivez attentivement le manuel : tous les membres d'une classe de personnages perdent une signification particulière (à quelques exceptions près). Et] perd sa signification spéciale s'il est placé d'abord dans la liste. Essayer:

$ echo '[123]' | sed 's/[][]//g'
123
$

Cela dit:

  1. à l'intérieur de extérieur [crochets], remplacez l'un des caractères inclus, à savoir:
    • ] et
    • [
  2. remplacer l'un d'eux par la chaîne vide - d'où la chaîne de remplacement vide //,
  3. remplacez-les partout ( globalement) - d'où le dernier g.

Encore, ] doit être le premier de la classe chaque fois qu'il est inclus.

29
Saparagus

Je ne sais pas pourquoi cela ne fonctionne pas, mais cela fonctionne:

echo '[123]' | sed 's/\(\[\|\]\)//g'

ou ca:

echo '[123]' | sed -r 's/(\[|\])//g'

Vous pouvez également essayer une approche différente et faire correspondre la chaîne à l'intérieur des crochets (en supposant que la chaîne peut être mise en correspondance facilement et n'est pas définie par les crochets):

echo '[123]' | egrep -o "[0-9]+"

J'ai les mêmes problèmes avec votre expression originale en utilisant grep donc je soupçonne que ce n'est pas seulement une chose sed.

Bizarrement, ceux-ci produisent des résultats différents mais l'un d'eux correspond à ce que vous voulez:

echo '[123]' | egrep -o '[^][]+'
123

echo '[123]' | egrep -o '[^[]]+'
3]

Appliquer cela à votre sed d'origine (et ajouter le /g modificateur pour supprimer les deux crochets):

echo '[123]' | sed 's/[][]//g'
123
11
Ladadadada

Pour tout supprimer avant et après les crochets:

$ echo '[123]' | sed 's/.*\[//;s/\].*//;'
123

Si vos données sont comme ça, cela signifie toujours commencer et terminer par des crochets:

$ echo '[123]' | sed 's/.//;s/.$//;'
123
4
Guru

Si vous avez une chaîne plus complexe comme 'abcdef [123] ghijk', vous pouvez également utiliser la commande bash interne 'cut' pour extraire le texte uniquement entre crochets:

$ echo 'abcdef[123]ghijk' | cut -d '[' -f 2 | cut -d ']' -f 1
123
1
valentt

Vous pouvez échapper au crochet d'ouverture à l'aide de \[. Pour le crochet de fermeture, utilisez []].

1
user2428118