9 votes

Bash : Diviser un fichier texte en mots avec des caractères non alphanumériques comme délimiteurs

Disons que " fichier texte "contient les éléments suivants :

lorem$ipsum-is9simply the.dummy text%of-printing

et que vous voulez imprimer chaque mot sur une ligne séparée. Cependant Les mots doivent être définis non seulement par des espaces, mais aussi par tous les caractères non alphanumériques. Ainsi, les résultats devraient ressembler à :

 lorem
 ipsum  
 is9simply  
 the  
 dummy  
 text  
 of  
 printing

Comment puis-je réaliser cela en utilisant le shell Bash ?


Quelques notes :

  • Il ne s'agit pas d'une question de devoir.

  • Le cas le plus simple, où les mots ne doivent être déterminés que par des espaces, est facile. Il suffit d'écrire :

    for i in `cat textfile`; do echo $i; done;

    fera l'affaire et reviendra :

     lorem$ipsum-is9simply
     the.dummy
     text%of-printing

    Pour séparer les mots par des caractères non alphanumériques, j'ai vu des solutions qui utilisent la variable d'environnement IFS (liens ci-dessous), mais je voudrais éviter d'utiliser IFS pour deux raisons : 1) cela nécessiterait (je pense) de définir l'IFS sur une longue liste de caractères non-alphanumériques. 2) Je trouve cela un peu laid.

  • Voici les deux questions-réponses connexes que j'ai trouvées
    Comment diviser une chaîne de caractères sur un délimiteur en Bash ?
    Comment diviser une ligne en mots séparés par un ou plusieurs espaces en bash ?

20voto

Jonathan Leffler Points 299946

Utilisez le tr commandement :

tr -cs 'a-zA-Z0-9' '\n' <textfile

Le -c ' est pour le complément des caractères spécifiés ; le ' -s permet d'extraire les doublons des remplacements ; la fonction 'a-zA-Z0-9' est l'ensemble des caractères alphanumériques (on pourrait peut-être ajouter _ aussi ?) ; le \n ' est le caractère de remplacement (nouvelle ligne). Vous pouvez également utiliser une classe de caractères qui est sensible à la locale (et qui peut inclure plus de caractères que la liste ci-dessus) :

tr -cs '[:alnum:]' '\n' <textfile

3voto

DigitalRoss Points 80400
$ awk -f splitter.awk < textfile

$ cat splitter.awk
{
  count0 = split($0, asplit, "[^a-zA-Z0-9]")
  for(i = 1; i <= count0; ++i) { print asplit[i] }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X