GNU/Linux >> Linux Esercitazione >  >> Linux

Perché non puoi usare cat per leggere un file riga per riga in cui ogni riga ha delimitatori

Il problema non è in cat , né nel for ciclo di per sé; è nell'uso delle virgolette. Quando scrivi:

for i in `cat file`

o (meglio):

for i in $(cat file)

o (in bash ):

for i in $(<file)

la shell esegue il comando e cattura l'output come una stringa, separando le parole dai caratteri in $IFS . Se vuoi che le righe vengano inserite in $i , devi giocherellare con IFS oppure usa il while ciclo continuo. Il while loop è meglio se c'è il pericolo che i file elaborati siano grandi; non deve leggere l'intero file in memoria tutto in una volta, a differenza delle versioni che usano $(...) .

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

Le virgolette attorno al "$i" sono generalmente una buona idea. In questo contesto, con il $IFS modificato , in realtà non è fondamentale, ma le buone abitudini sono buone abitudini anche così. Ha importanza nel seguente script:

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

quando il file di dati contiene più spazi tra le parole:

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

Uscita:

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

Senza le doppie virgolette:

$ 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
$

Puoi usare IFS variabile a specifica si desidera una nuova riga come separatore di campo:

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

il ciclo for accoppiato con una modifica del separatore di campo interno (IFS) leggerà il file come previsto

per un input

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

Ciclo for accoppiato con una modifica IFS

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

risulta in

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

Linux
  1. Perché Rm può rimuovere i file di sola lettura?

  2. Perché il descrittore di file viene aperto e letto solo una volta?

  3. Aggiungi una stringa di prefisso all'inizio di ogni riga

  4. Perché i file non possono essere manipolati da inode?

  5. Come posso creare un file in ogni cartella?

Perché uso exa invece di ls su Linux

Come leggere i file riga per riga in Bash

Come leggere un file riga per riga in Bash

Dov'è il file di intestazione <conio.h> su Linux? Perché non riesco a trovare <conio.h>?

Perché non posso eliminare questo file come root?

Perché alcune shell `read` incorporate non riescono a leggere l'intera riga dal file in `/proc`?