Pourquoi ne pouvez-vous pas utiliser cat pour lire un fichier ligne par ligne, chaque ligne a délimiteurs
J'ai un fichier texte qui contient quelque chose comme ceci:
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
J'ai écrit un script
for i in `cat file`
do
echo $i
done
Pour une raison quelconque, la sortie du script n'est pas de sortie le fichier ligne par ligne, mais les sauts de à la des virgules, ainsi que le retour à la ligne. Pourquoi le chat ou le "pour bla dans cat xyz
" faire cela et comment puis-je faire il PAS le faire? Je sais que je peux utiliser un
while read line
do
blah balh blah
done < file
mais je veux savoir pourquoi le chat ou le "bla" est en train de faire ce pour approfondir ma compréhension de commandes unix. Le chat de la page de man ne m'a pas aidé et en regardant ou en boucle dans le bash manuel n'a pas donné toutes les réponses (http://www.gnu.org/software/bash/manual/bashref.html). Merci d'avance pour votre aide.
IFS
.
OriginalL'auteur Classified | 2013-06-14
Vous devez vous connecter pour publier un commentaire.
Le problème n'est pas dans
cat
, ni dans lefor
boucle de soi; il est dans l'usage de retour citations. Lorsque vous écrivez:ou (mieux):
ou (dans
bash
):le shell exécute la commande et de la capture de la sortie comme une chaîne de caractères, en séparant les mots en caractères
$IFS
. Si vous souhaitez que les lignes d'entrée à$i
, soit vous avez à jouer avec desIFS
ou utiliser lewhile
boucle. Lewhile
boucle est mieux s'il y a un danger que les fichiers traités sera grand; il n'a pas à lire tout le fichier dans la mémoire de tous à la fois, à la différence des versions à l'aide de$(...)
.Les guillemets autour de la
"$i"
sont généralement une bonne idée. Dans ce contexte, avec la modification de$IFS
, en effet, il n'est pas essentiel, mais les bonnes habitudes sont de bonnes habitudes de même. C'est important dans le script suivant:lorsque le fichier de données contient plusieurs espaces entre les mots:
De sortie:
Sans les doubles quotes:
La valeur par défaut de l'IFS est (à l'aide d'un morceau de
bash
-parler)$' \t\n'
; en effet, elle se compose de blanc, tabulation, saut de ligne. C'est probablement ce qui modifie votre analyse. Quand vous dites "pauses à la virgule', tu veux dire qu'il se casse à l'espace après la virgule, je crois, ce qui est cohérent avec les FI contenant vide (et onglet et saut de ligne).merci encore pour l'explication. =)
OriginalL'auteur Jonathan Leffler
Vous pouvez utiliser
IFS
variable spécifique que vous voulez un retour à la ligne comme séparateur de champ:*
, qui sera élargi à une liste de noms dans le répertoire courant au cours de l'écho.OriginalL'auteur cforbish
FI - Interne séparateur de champ peut être réglé pour obtenir ce que vous voulez.
De lire une ligne entière à la fois, utilisez:
IFS=""
OriginalL'auteur Sudheej
pour la boucle couplé avec un changement de l'intérieur de l'séparateur de champ(IFS) va lire le fichier comme prévu
pour une entrée
Pour boucle couplé avec un IFS changement
résultats dans
IFS= read -r line
de préserver tous les espaces dans la ligne.La seule raison pour laquelle l'espacement est "perdu" avec la
while
boucle est parce que vous avez utiliséecho $line
plutôt queecho "$line"
. Si l'espacement est important, mettez la variable de référence dans des guillemets doubles.Comme chepner dit, ce doit être
read -r
pour éviter des effets secondaires indésirables (évaluation de barre oblique inverse des séquences d'échappement).OriginalL'auteur Dan675