Manipulation de mots en bash

Résolu/Fermé
rmzz5 Messages postés 35 Date d'inscription mercredi 21 mars 2018 Statut Membre Dernière intervention 10 octobre 2022 - 5 oct. 2022 à 15:44
rmzz5 Messages postés 35 Date d'inscription mercredi 21 mars 2018 Statut Membre Dernière intervention 10 octobre 2022 - 10 oct. 2022 à 06:47

Bonjour,

Je suis débutant en bash.

J'ai un fichier texte (in.txt). Sur chaque ligne, il peut y avoir un mot ou deux mots.

A l'aide d'un script bash, je voudrais parcourir ce fichier et faire rediriger les conditions suivantes dans un nouveau fichier (out.txt) :

- Si la ligne contient un mot, le diviser en deux. Exemple : football -> foot ball

- Si la ligne contient 2 mots, supprimer l'espace entre les deux mots. Exemple : papier ciseau -> papierciseau

Pourriez-vous m'aider ? svp
Windows / Chrome 106.0.0.0

3 réponses

mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
Modifié le 6 oct. 2022 à 10:15

Bonjour,

Tu peux commencer par lire ce tutoriel qui explique comment lire proprement un fichier ligne par ligne, en particulier si les lignes comportent plusieurs mots.

#!/bin/bash

input_file="toto.txt"

while read line  
do  
   echo "$line"
done < "$input_file"

Une fois la ligne lue, il faut regarder combien de mots elle contient. Tu peux regarder la commande wc (word count)

line="mot1 mot2" 
num_words=$(echo "$line" | wc -w)
echo "$num_words" # Affiche 2

Cela va te permettre de faire un test numérique (est-ce que ce résultat vaut 1 ou 2). Tout est expliqué dans ce lien. Attention cette syntaxe est spécifique à bash, pour un autre type de shell ou pour écrire le programme indépendamment du shell, il faudrait utiliser une autre syntaxe (voir opérateur -eq). Mais comme cette syntaxe moins naturelle et que l'exercice précise qu'on est en bash, utilisons la syntaxe de bash.

#!/bin/bash

if (( "$num_words" == 2 )); then
  echo "2 mots"
elif (( "$num_words" == 1 )); then 
  echo "1 mot"
else
  echo "oups"
fi
  • Ensuite, s'il y a deux mots, il suffit d'extraire les deux mots avec cut ou awk puis de les concaténer au moment de les imprimer avec echo. awk est un peu plus puissant que cut notamment car il n'impose pas d'avoir qu'un seul espace entre les deux mots, mais il est même tellement puissant qu'on pourrait écrire l'intégralité de ton exercice en awk. Bref, voici les deux manières de faire :
    word1=$(echo "$line" | cut -d" " -f1)
    word2=$(echo "$line" | cut -d" " -f2)
    word1=$(echo "$line" | awk '{print $1}')
    word2=$(echo "$line" | awk '{print $2}')
  • S'il n'y a qu'un mot, la manière dont scinder le mot n'est pas spécifiée. Du coup difficile de répondre. Mais admettons que tu sois arrivé à couper le mot en deux sous mots notés subword1 et subword2. Il suffit alors d'écrire :
    echo "$subword1" "$subword2"

Note que dans tout le code, je mets sciemment des guillemets autour des noms de variables. C'est quelque chose que je te recommande de faire systématiquement car ça évite les injections de code si une variable contient plusieurs mots et/ou des caractères spéciaux.

Bonne chance

0
rmzz5 Messages postés 35 Date d'inscription mercredi 21 mars 2018 Statut Membre Dernière intervention 10 octobre 2022
10 oct. 2022 à 06:47

Top merci beaucoup.

0
lEprofSonDkon Messages postés 211 Date d'inscription jeudi 13 décembre 2018 Statut Membre Dernière intervention 8 octobre 2022 13
8 oct. 2022 à 00:36

bon, on ne sait pas combien de mots, mais on veut le deuxième :

$ chaine='papier ciseau tuyau poele'
$ read -r menFout deuz menFout
$ echo "$deuz"
ciseau
$ echo "$menFout"
tuyau poele
$ # parce que seul le dernier `menFout' est assigné, en écrasant la précédente variable portant ce nom !
# on voit aussi que cette dernière variable prend tout le reste de la chaîne : tuyau poele...
0
lEprofSonDkon Messages postés 211 Date d'inscription jeudi 13 décembre 2018 Statut Membre Dernière intervention 8 octobre 2022 13
Modifié le 8 oct. 2022 à 00:42

et merci mamiemando pour ton énorme, excellent, et patient travail.

mais quand même : cut, awk... :/

;)

XD

0
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
9 oct. 2022 à 23:22

Ne t'inquiète pas, je ne le prends pas mal. Pour moi le résultat est équivalent. Je n'ai jamais pensé à utiliser read pour couper un mot, donc ta remarque est intéressante. Après en terme de performances, je ne pense pas qu'utiliser l'une de ces trois solutions soit drastiquement différent, et toutes sont correctes.

0