De meest efficiënte manier om een bestand te verwerken, regel voor regel, is om een bash script te ontwikkelen en het bestand als invoer voor het script te geven. Dit kan gedaan worden door een bestand regel voor regel te lezen in een lus. Bash behandelt zo elke regel als een element in een lijst. Als we begrijpen hoe we de inhoud van een groot gegevensbestand regel voor regel kunnen verwerken, hoeven we ze niet steeds te openen. Er zijn veel manieren om elke regel te lezen met Bash.
Om dit te demonstreren maken we een tekstbestand met de naam voorbeeld.txt met de volgende inhoud:
dany@pindabook:~$echo "Frankrijk
>Singapore
>Peru
>Ghana
>Mexico
>Australië" > voorbeeld.txt
Op het einde van elke regel druk je Return. Zolang de opdracht niet volledig is, krijg je het > teken om aan te duiden dat je de opdracht op de vorige regel nog moet vervolledigen. Controleer de inhoud van dit bestand met:
dany@pindabook:~$ cat voorbeeld.txt
Frankrijk
Singapore
Peru
Ghana
Mexico
Australië
Een while-lus in combinatie met de read
opdracht leest elke regel uit het bestand en slaat in elke stap de inhoud van de regel op in een variabele.
Maak met een teksteditor (bijvoorbeeld nano) het script regelverwerking.sh aan:
dany@pindabook:~$ nano regelverwerking.sh
Met de volgende inhoud:
#!/bin/bash
while read -r line
do
echo "$line"
done < voorbeeld.txt
Sla het script op met de sneltoets Ctrl+o en bevestig de bestandsnaam met Return. Verlaat de teskteditor nano met de sneltoets Ctrl+x.
Elke keer dat de while-lus wordt doorlopen, leest de read
opdracht een regel van het bestand en wijst het toe aan de bash shell variabele $line
.
Na het lezen van de laatste regel van het bestand stopt de while-lus.
De -r
vlag van de read opdracht voorkomt de interpretatie van backslash-escaped karakters tijdens het lezen.
Test het script met:
dany@pindabook:~$ bash regelverwerking.sh
Frankrijk
Singapore
Peru
Ghana
Mexico
Australië
Een bestandsdescriptor is een geheel getal dat door een Linux proces wordt gebruikt om een open bestand op een unieke manier te identificeren. Er bestaat ten minsten één bestandsdescriptor voor elk open bestand. De eerste drie bestandsdescriptors zijn standaard STDIN (0), STDOUT (1) en STDERR (2).
Pas het vorige script aan tot:
#!/bin/bash
while read -r -u5 line
do
echo "$line"
done 5< voorbeeld.txt
Elke keer dat de while-lus wordt doorlopen, leest de read
opdracht invoer van een bestandsdescriptor gespecificeerd door de -u
optie en het bestandsdescriptornummer.
De inhoud van het invoerbestand wordt naar de opgegeven bestandsdescriptor gestuurd.
Er wordt aangeraden om een getal tussen 4 en 9 te gebruiken om conflicten met de interne bestandsdescriptors van de terminal te voorkomen.
dany@pindabook:~$ bash regelverwerking.sh
Frankrijk
Singapore
Peru
Ghana
Mexico
Australië
Om de inhoud van een bestand per regel weer te geven, kun je een for-lus doolopen via de cat
opdracht.
Met de for-lus kunnen de regels via de uitvoer van de cat
opdracht tot het einde van het bestand worden weergegeven.
#!/bin/bash
for line in $(cat voorbeeld.txt)
do
echo "$line"
done
Elke keer dat de for-lus wordt doorlopen, wordt één regel van de uitvoer van de cat
opdracht in de variabele $line
opgeslagen.
Vervolgens wordt de waarde die is opgeslagen in de variabele afgedrukt met de echo
opdracht totdat het einde van het bestand is bereikt.
De lus stopt nadat de laatste regel is verwerkt.
Deze methode maakt gebruik van een here string om de inhoud van het bestand te leveren aan de read
opdracht.
Here string wordt gebruikt als invoeromleiding (input redirection) van een tekenreeks (string), een bestand of een variabele.
Het wordt geconstrueerd met de <<<
operator om een tekenreeks door te sturen naar een opdracht.
#!/bin/bash
while read -r line
do
echo "$line"
done <<< $(cat voorbeeld.txt )
De here string levert de uitvoer gegenereerd door de cat
opdracht als invoer voor de read
opdracht.
In de lus wordt dit regel voor regel gelezen en opgeslagen in de bash variabele $line
.
Om de inhoud van een bestand in afzonderlijke regels weer te geven, kan de while-lus worden doorlopen met de Internal Field Separator.
De optie IFS=
wordt ingesteld als een lege tekenreeks.
Dit helpt om de spaties te behouden.
#!/bin/bash
while IFS= read -r line
do
echo "$line"
done < <(cat voorbeeld.txt)
Deze techniek staat ook bekend als proces- of opdrachtsubstitutie waarbij een bash opdracht wordt uitgevoerd en de uitvoer wordt opgeslagen in een variabele of wordt doorgegeven aan een andere opdracht. Hier is de standaard uitvoer van het proces beschikbaar als een bestand dat op zijn beurt wordt ingevoerd in de standaard invoer van een ander proces. Het invoerbestand wordt aangeleverd en elke regel wordt apart weergegeven.
Deze keer blijft het opruimen beperkt tot het verwijderen van het script regelverwerking.sh en het tekstbestand voorbeeld.txt:
dany@pindabook:~$ rm regelverwerking.sh voorbeeld.txt