Supposons que vous ayez ce fichier:
$ cat /tmp/test.txt
Line 1
Line 2 has leading space
Line 3 followed by blank line
Line 5 (follows a blank line) and has trailing space
Line 6 has no ending CR
Il existe quatre éléments qui modifieront la signification de la sortie de fichier lue par de nombreuses solutions Bash:
- La ligne vierge 4;
- Espaces de début ou de fin sur deux lignes;
- Conserver la signification des lignes individuelles (c.-à-d., Chaque ligne est un enregistrement);
- La ligne 6 ne se termine pas par un CR.
Si vous souhaitez que le fichier texte ligne par ligne, y compris les lignes vides et les lignes de terminaison sans CR, vous devez utiliser une boucle while et vous devez avoir un test alternatif pour la ligne finale.
Voici les méthodes qui peuvent changer le fichier (par rapport à ce qui cat
retourne):
1) Perdez la dernière ligne et les espaces de début et de fin:
$ while read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txt
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'
(Si vous le faites à la while IFS= read -r p; do printf "%s\n" "'$p'"; done </tmp/test.txt
place, vous conservez les espaces de début et de fin mais perdez toujours la dernière ligne si elle ne se termine pas par CR)
2) L'utilisation de la substitution de processus avec cat
will lit le fichier entier en une seule gorgée et perd la signification des lignes individuelles:
$ for p in "$(cat /tmp/test.txt)"; do printf "%s\n" "'$p'"; done
'Line 1
Line 2 has leading space
Line 3 followed by blank line
Line 5 (follows a blank line) and has trailing space
Line 6 has no ending CR'
(Si vous enlevez le "
de $(cat /tmp/test.txt)
vous lisez le fichier mot par mot plutôt qu'une gorgée. Aussi probablement pas ce qui est prévu ...)
La façon la plus robuste et la plus simple de lire un fichier ligne par ligne et de conserver tout l'espacement est:
$ while IFS= read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </tmp/test.txt
'Line 1'
' Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space '
'Line 6 has no ending CR'
Si vous souhaitez supprimer les espaces de tête et d'échange, supprimez la IFS=
pièce:
$ while read -r line || [[ -n $line ]]; do printf "'%s'\n" "$line"; done </tmp/test.txt
'Line 1'
'Line 2 has leading space'
'Line 3 followed by blank line'
''
'Line 5 (follows a blank line) and has trailing space'
'Line 6 has no ending CR'
(Un fichier texte sans terminaison \n
, si vous pouvez compter sur l'arrière tout assez commun, est considéré comme rompu sous Posix. \n
Vous n'avez pas besoin || [[ -n $line ]]
dans lawhile
boucle.)
Plus à la FAQ BASH