web-dev-qa-db-fra.com

sed remplace tous les onglets et espaces par un seul espace

J'ai une chaîne comme celle-ci:

test.de.          1547    IN      SOA     ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600

maintenant, je veux remplacer tous les onglets/espaces entre les enregistrements par un seul espace afin que je puisse facilement l'utiliser avec cut -d " "

J'ai essayé ce qui suit:

sed "s/[\t[:space:]]+/[:space:]/g"

et diverses variantes, mais n'a pas pu le faire fonctionner. Des idées?

26
Zulakis

Utilisation sed -e "s/[[:space:]]\+/ /g"

Voici une explication:

[   # start of character class

  [:space:]  # The POSIX character class for whitespace characters. It's
             # functionally identical to [ \t\r\n\v\f] which matches a space,
             # tab, carriage return, newline, vertical tab, or form feed. See
             # https://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes

]   # end of character class

\+  # one or more of the previous item (anything matched in the brackets).

Pour votre remplacement, vous souhaitez uniquement insérer un espace. [:space:] ne fonctionnera pas là car c'est une abréviation pour une classe de caractère et le moteur d'expression régulière ne saurait pas quel caractère y mettre.

Le + doit être échappé dans l'expression régulière, car avec le moteur d'expression régulière de sed + est un caractère normal alors que \+ est un métacaractère pour "un ou plusieurs". À la page 86 de Mastering Regular Expressions, Jeffrey Friedl mentionne dans une note de bas de page que ed et grep ont utilisé des parenthèses échappées parce que "Ken Thompson pensait que les expressions régulières seraient utilisées pour travailler principalement avec du code C, où il fallait faire correspondre raw les parenthèses seraient plus courantes que les références arrières. " Je suppose qu'il ressentait la même chose à propos du signe plus, d'où la nécessité de lui échapper pour l'utiliser comme métacaractère. Il est facile de se faire tromper par cela.

Dans sed, vous devrez vous échapper +, ?, |, (, et ). ou utilisez -r pour utiliser l'expression rationnelle étendue (il ressemble alors à sed -r -e "s/[[:space:]]\+/ /g" ou sed -re "s/[[:space:]]\+/ /g"

44
Starfish

Vous pouvez utiliser le -s ("squeeze") option de tr:

$ tr -s '[:blank:]' <<< 'test.de.          1547    IN      SOA     ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600'
test.de. 1547 IN SOA ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600

Le [:blank:] La classe de caractères comprend à la fois des espaces et des tabulations.

6
Benjamin W.