web-dev-qa-db-fra.com

Remplacez tous les espaces par un saut de ligne / marque de paragraphe pour créer une liste de mots

J'essaie de lister du vocabulaire pour un texte grec que nous traduisons en classe. Je veux remplacer chaque espace ou tabulation par une marque de paragraphe afin que chaque mot apparaisse sur sa propre ligne. Quelqu'un peut-il me donner la commande sed et expliquer ce que je fais? J'essaie encore de comprendre.

62
DavidR

Pour les versions relativement modernes de sed, éditez l’entrée standard pour obtenir la sortie standard avec

$ echo 'τέχνη βιβλίο γη κήπος' | sed -E -e 's/[[:blank:]]+/\n/g'
τέχνη
βιβλίο
γη
κήπος

Si vos mots de vocabulaire sont dans des fichiers nommés lesson1 et lesson2, redirige la sortie standard de sed vers le fichier all-vocab avec

sed -E -e 's/[[:blank:]]+/\n/g' lesson1 lesson2 > all-vocab

Ce que cela veut dire:

  • Le classe de caractères[[:blank:]] correspond à un seul caractère d’espace ou à un seul caractère de tabulation.
    • Utilisation [[:space:]] à la place pour faire correspondre tout caractère d'espacement (généralement, espace, tabulation, nouvelle ligne, retour chariot, saut de page et onglet vertical).
    • Le + quantificateur signifie correspond à un ou plusieurs motifs précédents.
    • Alors [[:blank:]]+ est une séquence d'un ou de plusieurs caractères qui sont tous des espaces ou des tabulations.
  • Le \n dans le remplacement correspond à la nouvelle ligne souhaitée.
  • Le /g modifie à la fin signifie que vous effectuez la substitution autant de fois que possible et non une seule fois.
  • Le -E Option indique à Sed d’utiliser la syntaxe POSIX de regex étendu et en particulier, dans ce cas, le + quantificateur. Sans pour autant -E, votre commande sed devient sed -e 's/[[:blank:]]\+/\n/g'. (Notez l'utilisation de \+ plutôt que simple +.)

Regex compatibles Perl

Pour ceux qui sont familiers avec les expressions rationnelles compatibles Perl et un sed compatible PCRE, utilisez \s+ pour faire correspondre les exécutions d'au moins un caractère d'espacement, comme dans

sed -E -e 's/\s+/\n/g' old > new

ou

sed -e 's/\s\+/\n/g' old > new

Ces commandes lisent les entrées du fichier old et écrivent le résultat dans un fichier nommé new dans le répertoire en cours.

Portabilité maximale, cruauté maximale

Pour revenir à presque toutes les versions de sed depuis Version 7 Unix , l’appel de commande est un peu plus baroque.

$ echo 'τέχνη βιβλίο γη κήπος' | sed -e 's/[ \t][ \t]*/\
/g'
τέχνη
βιβλίο
γη
κήπος

Remarques:

  • Ici, nous n’assumons même pas l’existence de l’humble + quantifier et simulez-le avec un seul espace ou tabulation ([ \t]) suivi de zéro ou plus ([ \t]*).
  • De même, en supposant que sed ne comprend pas \n pour newline, nous devons l’inclure sur la ligne de commande mot à mot.
    • Le \ et la fin de la première ligne de la commande est un marqueur de continuation qui échappe à la nouvelle ligne suivante, et le reste de la commande se trouve sur la ligne suivante.
      • Remarque: Aucun espace ne doit précéder le retour à la ligne échappé. C'est-à-dire que la fin de la première ligne doit être exactement barre oblique inverse suivie de la fin de la ligne.
    • Ce processus sujet aux erreurs permet de comprendre pourquoi le monde est passé aux caractères visibles et vous devrez faire preuve de prudence en essayant la commande avec copier-coller.

Note sur les barres obliques inverses et les citations

Les commandes ci-dessus utilisent toutes des guillemets simples ('') plutôt que des guillemets doubles (""). Considérer:

$ echo '\\\\' "\\\\"
\\\\ \\

En d'autres termes, le shell applique différentes règles d'échappement aux chaînes à guillemets simples par rapport aux chaînes à guillemets doubles. Vous voulez généralement protéger toutes les barres obliques inverses courantes dans les expressions rationnelles avec des guillemets single.

93
Greg Bacon

La manière portable de faire ceci est:

sed -e 's/[ \t][ \t]*/\
/g'

C'est une nouvelle ligne réelle entre la barre oblique inverse et la barre oblique-g. De nombreuses implémentations de sed ne connaissent pas \n, vous avez donc besoin d’une nouvelle ligne. La barre oblique inverse avant la nouvelle ligne empêche sed de se fâcher contre la nouvelle ligne. (dans les scripts sed, les commandes sont normalement terminées par des nouvelles lignes)

Avec GNU sed, vous pouvez utiliser \n dans la substitution et\s dans la regex:

sed -e 's/\s\s*/\n/g'

GNU sed supporte aussi les expressions rationnelles "étendues" (c'est le style egrep, pas le style Perl) si vous lui attribuez le drapeau -r, vous pouvez donc utiliser +:

sed -r -e 's/\s+/\n/g'

Si cela concerne uniquement Linux, vous pouvez probablement utiliser la commande GNU, mais si vous souhaitez que cela fonctionne sur des systèmes avec une version non-GNU (par exemple: BSD, Mac OS-X) , vous voudrez peut-être choisir l’option plus portable.

56
Laurence Gonsalves

Tous les exemples énumérés ci-dessus pour sed reposent sur une plateforme ou une autre. Aucun d’entre eux ne fonctionne avec la version de sed fournie sur Mac.

Cependant, l'expression rationnelle de Perl fonctionne de la même manière sur toutes les machines sur lesquelles Perl est installé:

Perl -pe 's/\s+/\n/g' file.txt

Si vous souhaitez enregistrer la sortie:

Perl -pe 's/\s+/\n/g' file.txt > newfile.txt

Si vous ne voulez que des occurrences uniques de mots:

Perl -pe 's/\s+/\n/g' file.txt | sort -u > newfile.txt
9
Earl Ruby
  1. option 1

    echo $(cat testfile)
    
  2. Option 2

    tr ' ' '\n' < testfile
    
6
RAJ

Cela devrait faire le travail:

sed -e 's/[ \t]+/\n/g'

[ \t] signifie un espace OR un onglet. Si vous voulez un espace quelconque, vous pouvez aussi utiliser \s.

[ \t]+ signifie autant d’espaces OR tabulations que vous le souhaitez (mais au moins un))

s/x/y/ signifie que le motif x est remplacé par y (ici \n est une nouvelle ligne)

Le g à la fin signifie que vous devez répéter autant de fois que cela se produit dans chaque ligne.

4
Tristram Gräbener

Vous pouvez utiliser POSIX [[:blank:]] pour correspondre à un caractère d’espace blanc horizontal.

sed 's/[[:blank:]]\+/\n/g' file

ou vous pouvez utiliser [[:space:]] au lieu de [[:blank:]] également.

Exemple:

$ echo 'this  is a sentence' | sed 's/[[:blank:]]\+/\n/g'
this
is
a
sentence
4
Avinash Raj

Vous pouvez aussi le faire avec xargs:

cat old | xargs -n1 > new

ou

xargs -n1 < old > new
2
FranMowinckel

Utiliser gawk:

gawk '{$1=$1}1' OFS="\n" file
0
ghostdog74