web-dev-qa-db-fra.com

Comment lire la ligne complète dans la boucle 'for' avec des espaces

J'essaie d'exécuter une boucle for pour le fichier et je souhaite afficher la ligne entière. Mais au lieu de cela, il affiche uniquement le dernier mot. Je veux la ligne complète.

for j in `cat ./file_wget_med`

do
echo $j

done

résultat après exécution:

Found.

Voici mes données:

$ cat file_wget_med
2013-09-11 14:27:03 ERROR 404: Not Found.
120
user192118

La boucle for se scinde lorsqu'elle voit des espaces tels que des espaces, des tabulations ou des nouvelles lignes. Donc, vous devriez utiliser IFS (séparateur de champ interne) :

IFS=$'\n'       # make newlines the only separator
for j in $(cat ./file_wget_med)    
do
    echo "$j"
done
166
Radu Rădeanu

for boucles divisées sur n'importe quel espace blanc (espace, tabulation, nouvelle ligne) par défaut; La façon la plus simple de travailler sur un ligne à la fois consiste à utiliser une boucle while read à la place, qui se scinde à la nouvelle ligne:

while read i; do echo "$i"; done < ./file_wget_med

Je voudrais attendre votre commande cracher un mot par ligne (c'est ce qui s'est passé lorsque je l'ai testé avec un fichier de mon choix). Si quelque chose d'autre se passe, je ne suis pas sûr de ce qui pourrait en être la cause.

80
evilsoup
#!/bin/bash
files=`find <subdir> -name '*'`
while read -r fname; do
    echo $fname
done <<< "$files"

Vérifié le travail, pas la ligne que vous voulez probablement mais il est impossible de faire si élégamment.

19
Mitchell Currie

Voici une légère extension de la réponse de Mitchell Currie, que j'aime bien à cause du petit nombre d'effets secondaires, ce qui évite de devoir définir une variable:

#!/bin/bash
while read -r fname; do
    echo $fname
done <<< "`find <subdir>`"
5
Dandalf

Je l'écrirais comme ceci:

cat ./file_wget_med | while read -r j
do
    echo $j
done

car cela nécessite moins de modifications dans le script d'origine (à l'exception de la solution utilisant IFS, mais elle modifie le comportement bash non seulement pour cette instruction de contrôle de boucle).

1
mik