J'ai un fichier texte contenant un nom de fichier dans chaque ligne:
111_c4l5r120.png
123_c4l4r60.png
135_c4l4r180.png
147_c4l3r60.png
15_c4l1r120.png
...
Je veux le convertir sous cette forme:
111_c4l5r120.png 111
123_c4l4r60.png 123
135_c4l4r180.png 135
147_c4l3r60.png 147
15_c4l1r120.png 15
...
en utilisant ce code:
#!/bin/bash
while IFS='' read -r line || [[ -n "$line" ]]; do
echo "$line" >> output.txt
echo "$line" | cut -d'_' -f 1 >> output.txt
done < "$1"
mais le résultat est:
111_c4l5r120.png
111
123_c4l4r60.png
123
135_c4l4r180.png
135
147_c4l3r60.png
147
15_c4l1r120.png
15
...
Comment dois-je changer mon script pour avoir la sortie désirée?
Réponses:
Sauf si vous avez un besoin spécifique d'utiliser le shell pour cela, la réponse de terdon fournit de meilleures alternatives.
Puisque vous utilisez
bash
(comme indiqué dans le shebang du script), vous pouvez utiliser l'-n
option pour faire écho:Ou vous pouvez utiliser les fonctionnalités du shell pour traiter la ligne sans utiliser
cut
:(en remplaçant les deux
echo
lignes).Alternativement,
printf
ferait aussi l'affaire, fonctionne dans n'importe quel shell POSIX et est généralement meilleur (voir Pourquoi printf est-il meilleur qu'echo? Pour plus de détails):ou
(À proprement parler, en clair
/bin/sh
, ceecho -n
n'est pas portable . Puisque vous utilisez explicitement,bash
c'est OK ici.)la source
Ne faites pas ce genre de choses dans la coquille! Il est beaucoup plus complexe que nécessaire, sujet aux erreurs et de loin, beaucoup plus lent. Il existe de nombreux outils conçus pour une telle manipulation de texte. Par exemple, dans
sed
(en supposant ici des implémentations GNU ou BSD récentes pour-E
):Ou, pour tout
sed
:Perl:
awk:
la source
sed
unsed 's/\([^_]*\).*/& \1/' file
pour une portabilité supplémentaire. Le fait est que vous pouvez compterawk
etsed
être là plus que vous ne pouvez compter sur à peu près n'importe quoi d'autre.Vous voilà:
Production:
la source