GNU/Linux >> Tutoriels Linux >  >> Linux

Pourquoi ne pouvez-vous pas utiliser cat pour lire un fichier ligne par ligne où chaque ligne a des délimiteurs

Le problème n'est pas dans cat , ni dans le for boucle en soi ; c'est dans l'utilisation des guillemets. Lorsque vous écrivez soit :

for i in `cat file`

ou (mieux):

for i in $(cat file)

ou (en bash ):

for i in $(<file)

le shell exécute la commande et capture la sortie sous forme de chaîne, en séparant les mots au niveau des caractères dans $IFS . Si vous voulez que les lignes entrent dans $i , vous devez soit jouer avec IFS ou utilisez le while boucle. Le while loop est préférable s'il existe un risque que les fichiers traités soient volumineux ; il n'est pas nécessaire de lire tout le fichier en mémoire en une seule fois, contrairement aux versions utilisant $(...) .

IFS='
'
for i in $(<file)
do echo "$i"
done

Les guillemets autour du "$i" sont généralement une bonne idée. Dans ce contexte, avec le $IFS modifié , ce n'est en fait pas critique, mais les bonnes habitudes sont quand même de bonnes habitudes. Cela compte dans le script suivant :

old="$IFS"
IFS='
'
for i in $(<file)
do
   (
   IFS="$old"
   echo "$i"
   )
done

lorsque le fichier de données contient plusieurs espaces entre les mots :

$ cat file
abc                  123,         comma
the   quick   brown   fox
jumped   over   the   lazy   dog
comma,   comma
$ 

Sortie :

$ sh bq.sh
abc                  123,         comma
the   quick   brown   fox
jumped   over   the   lazy   dog
comma,   comma
$

Sans les guillemets :

$ cat bq.sh
old="$IFS"
IFS='
'
for i in $(<file)
do
   (
   IFS="$old"
   echo $i
   )
done
$ sh bq.sh
abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma
$

Vous pouvez utiliser IFS variable pour spécifier que vous voulez une nouvelle ligne comme séparateur de champ :

IFS=$'\n'
for i in `cat file`
do
   echo $i
done

la boucle for couplée à un changement du séparateur de champ interne (IFS) lira le fichier comme prévu

pour une entrée

abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma

Boucle For couplée à un changement d'IFS

old_IFS=$IFS
IFS=$'\n'
for i in `cat file`
do
        echo $i
done
IFS=$old_IFS

résultats en

abc 123, comma
the quick brown fox
jumped over the lazy dog
comma, comma

Linux
  1. Cat ligne X à ligne Y sur un énorme fichier ?

  2. Pourquoi Rm peut-il supprimer les fichiers en lecture seule ?

  3. Boîte occupée lire le fichier ligne par ligne ?

  4. Pouvez-vous utiliser des ancres ^ $ avec Ls ?

  5. Pourquoi le descripteur de fichier est-il ouvert et lu une seule fois ?

Pourquoi j'utilise exa au lieu de ls sous Linux

Comment lire des fichiers ligne par ligne dans Bash

Comment lire un fichier ligne par ligne dans Bash

Pourquoi utiliser shm_open ?

Où vont les métadonnées lorsque vous enregistrez un fichier ?

Pourquoi certains shells `read` intégrés ne parviennent pas à lire toute la ligne du fichier dans `/proc` ?