Stel dat ik dit bestand heb:
hello world hello world 
Dit programma
#!/bin/bash for i in $(cat $1); do echo "tester: $i" done 
outputs
tester: hello tester: world tester: hello tester: world 
 Ik “zou graag de for herhaal over elke regel afzonderlijk en negeer echter witruimten, dwz de laatste twee regels moeten worden vervangen door 
tester: hello world 
 Aanhalingstekens gebruiken for i in "$(cat $1)"; resulteert erin dat i het hele bestand in één keer wordt toegewezen. Wat moet ik wijzigen? 
Antwoord
 (9 jaar later 🙂 
 Beide verstrekte antwoorden zouden mislukken op bestanden zonder een nieuwe regel aan het einde, dit zal effectief de laatste regel overslaan, geen fouten produceren, zou tot een ramp leiden (hard geleerd way :). 
De beste beknopte oplossing die ik tot nu toe heb gevonden is dat “Just Works” (in zowel bash als sh):
while IFS="" read -r LINE || [ -n "${LINE}" ]; do echo "processing line: ${LINE}" done < /path/to/input/file.txt 
Zie deze StackOverflow-discussie voor een meer diepgaande discussie: Hoe “while read “(Bash) om de laatste regel in een bestand te lezen als er geen nieuwe regel aan het einde van het bestand staat?
Let op: deze benadering voegt een extra nieuwe regel toe aan de laatste regel als die er is geen al.
Reacties
- Leuke vangst, bedankt! Let op de " Pas op dat dit een extra nieuwe regel toevoegt aan EOF als die er al is. " opmerking echter
 - Tobias, ik ' zal dit als een opmerking toevoegen, bedankt.
 
Antwoord
 Met for en  IFS : 
#!/bin/bash IFS=$"\n" # make newlines the only separator set -f # disable globbing for i in $(cat < "$1"); do echo "tester: $i" done 
 Merk echter op dat het lege regels zal overslaan omdat  nieuwe regel  een IFS-witruimte-teken is, reeksen daarvan tellen als 1 en de voorste en achterste worden genegeerd. Met zsh en ksh93 (niet bash) kun je deze wijzigen in IFS=$"\n\n" om nieuwe regel niet speciaal te behandelen, merk er echter op dat alle  achterliggende  tekens voor nieuwe regels (dus inclusief lege regels aan het einde) altijd zullen worden verwijderd door de opdrachtsubstitutie. 
 Of  met read  (niet meer cat ): 
#!/bin/bash while IFS= read -r line; do echo "tester: $line" done < "$1" 
Daar blijven lege regels behouden, maar merk op dat het de laatste regel zou overslaan als deze niet correct werd gescheiden door een nieuw-regel-teken.
Reacties
-  bedankt, ik wist niet ' niet dat iemand 
<in een hele lus. Hoewel het nu volkomen logisch is, zag ik het -  Ik zie 
IFS \ read -r line' in second example. Is reallyIFS = `nodig? IMHO het genoeg om te zeggen:while read -r line; do echo "tester: $line"; done < "$1" -  @GrzegorzWierzowiecki 
IFS=schakelt het verwijderen van voorloop- en volgspaties uit. Zie Inwhile IFS= read.., waarom heeft IFS geen effect? -  @BenMares Om globbing te voorkomen uitdrukkingen die mogelijk voorkomen in de tekst die we lezen, worden uitgebreid naar overeenkomende bestandsnamen. Probeer bijvoorbeeld 
printf '%s\n' '*o' 'bar' >afile; touch foo; IFS=$'\n'; for i in $(cat afile); do echo "$i"; done. -  Een 
while IFS= read -r line || [ "$line" ]; doverwerkt een regel aan het einde die niet correct wordt gescheiden door een teken voor een nieuwe regel (maar het wordt weer toegevoegd). 
Antwoord
 Voor wat het waard is, moet ik doen dat vrij vaak, en ik kan me nooit de exacte manier herinneren om while IFS= read... te gebruiken, dus definieerde ik de volgende functie in mijn bash-profiel: 
# iterate the line of a file and call input function iterlines() { (( $# < 2 )) && { echo "Usage: iterlines <File> <Callback>"; return; } local File=$1 local Func=$2 n=$(cat "$File" | wc -l) for (( i=1; i<=n; i++ )); do "$Func" "$(sed "${i}q;d" "$File")" done } 
 Deze functie bepaalt eerst het aantal regels in het bestand, gebruikt vervolgens sed om regel na regel te extraheren, en geeft elke regel als een enkel stringargument door aan een gegeven functie. Ik veronderstel dat dit erg inefficiënt kan worden met grote bestanden, maar dat is tot dusver geen probleem voor mij geweest (suggesties om dit welkom te verbeteren natuurlijk). 
Het gebruik is best aardig IMO:
>> cat example.txt # note the use of spaces, whitespace, etc. a/path This is a sentence. "wi\th quotes" $End >> iterlines example.txt echo # preserves quotes, $ and whitespace a/path This is a sentence. "wi\th quotes" $End >> x() { echo "$#"; }; iterlines example.txt x # line always passed as single input string 1 1 1 1 1