Lees een bestand regel voor regel door de waarde toe te wijzen aan een variabele

Ik heb het volgende .txt-bestand:

Marco
Paolo
Antonio

Ik wil het regel voor regel lezen en voor elke regel wil ik een .txt regelwaarde toewijzen aan een variabele. Stel dat mijn variabele $name is, dan is de stroom:

  • Eerste regel uit bestand lezen
  • Wijs $name = “Marco” toe
  • Voer wat taken uit met $name
  • Tweede regel uit bestand lezen
  • Wijs $name = “Paolo” toe

Antwoord 1, autoriteit 100%

Het volgende leest een bestand dat regel voor regel als argument wordt doorgegeven:

while IFS= read -r line; do
    echo "Text read from file: $line"
done < my_filename.txt

Dit is het standaardformulier voor het in een lus lezen van regels uit een bestand. Uitleg:

  • IFS= (of IFS='') voorkomt dat voorloop-/achterliggende witruimte wordt bijgesneden.
  • -r voorkomt dat backslash-escapes worden geïnterpreteerd.

Of je kunt het in een bash-bestandhelperscript plaatsen, voorbeeldinhoud:

#!/bin/bash
while IFS= read -r line; do
    echo "Text read from file: $line"
done < "$1"

Als het bovenstaande is opgeslagen in een script met bestandsnaam readfile, kan het als volgt worden uitgevoerd:

chmod +x readfile
./readfile filename.txt

Als het bestand geen standaard POSIX-tekstbestand is (= niet afgesloten met een teken voor een nieuwe regel), kan de lus worden aangepast om achterliggende gedeeltelijke regels te verwerken:

while IFS= read -r line || [[ -n "$line" ]]; do
    echo "Text read from file: $line"
done < "$1"

Hier, || [[ -n $line ]] voorkomt dat de laatste regel wordt genegeerd als deze niet eindigt met een \n (aangezien read een niet- nul exit-code wanneer het EOF tegenkomt).

Als de commando’s in de lus ook worden gelezen vanuit standaardinvoer, kan de bestandsdescriptor die wordt gebruikt door read toevallig worden gebruikt voor iets anders (vermijd de standaard bestandsdescriptors), bijv.:

while IFS= read -r -u3 line; do
    echo "Text read from file: $line"
done 3< "$1"

(Niet-Bash-shells kennen read -u3 misschien niet; gebruik in plaats daarvan read <&3.)


Antwoord 2, autoriteit 22%

Ik raad je aan om de -r vlag te gebruiken voor read wat staat voor:

-r  Do not treat a backslash character in any special way. Consider each
    backslash to be part of the input line.

Ik citeer van man 1 read.

Een ander ding is om een ​​bestandsnaam als argument te nemen.

Hier is de bijgewerkte code:

#!/usr/bin/bash
filename="$1"
while read -r line; do
    name="$line"
    echo "Name read from file - $name"
done < "$filename"

Antwoord 3, autoriteit 9%

Als u de volgende Bash-sjabloon gebruikt, kunt u één waarde tegelijk uit een bestand lezen en verwerken.

while read name; do
    # Do what you want to $name
done < filename

Antwoord 4, autoriteit 6%

#! /bin/bash
cat filename | while read LINE; do
    echo $LINE
done

Antwoord 5

Gebruik:

filename=$1
IFS=$'\n'
for next in `cat $filename`; do
    echo "$next read from $filename" 
done
exit 0

Als je IFS anders hebt ingesteld, krijg je vreemde resultaten.


Antwoord 6

Veel mensen hebben een oplossing gepost die te veel geoptimaliseerd is. Ik denk niet dat het onjuist is, maar ik denk nederig dat een minder geoptimaliseerde oplossing wenselijk zal zijn zodat iedereen gemakkelijk kan begrijpen hoe dit werkt. Hier is mijn voorstel:

#!/bin/bash
#
# This program reads lines from a file.
#
end_of_file=0
while [[ $end_of_file == 0 ]]; do
  read -r line
  # the last exit status is the 
  # flag of the end of file
  end_of_file=$?
  echo $line
done < "$1"

Antwoord 7

Als u zowel het invoerbestand als de gebruikersinvoer (of iets anders van stdin) moet verwerken, gebruik dan de volgende oplossing:

#!/bin/bash
exec 3<"$1"
while IFS='' read -r -u 3 line || [[ -n "$line" ]]; do
    read -p "> $line (Press Enter to continue)"
done

Gebaseerd op het geaccepteerde antwoord en op de bash-hackers omleidingshandleiding.

Hier openen we de bestandsdescriptor 3 voor het bestand dat is doorgegeven als het scriptargument en vertellen read om deze descriptor als invoer te gebruiken (-u 3). Dus laten we de standaard invoerdescriptor (0) gekoppeld aan een terminal of een andere invoerbron die gebruikersinvoer kan lezen.


Antwoord 8

Voor de juiste foutafhandeling:

#!/bin/bash
set -Ee    
trap "echo error" EXIT    
test -e ${FILENAME} || exit
while read -r line
do
    echo ${line}
done < ${FILENAME}

Antwoord 9

Gebruik IFS-tool (intern veldscheidingsteken) in bash, definieert het teken dat wordt gebruikt om regels in tokens te scheiden, bevat standaard <tab> /<spatie> /<newLine>

stap 1: Laad de bestandsgegevens en voeg deze toe aan de lijst:

# declaring array list and index iterator
declare -a array=()
i=0
# reading file in row mode, insert each line into array
while IFS= read -r line; do
    array[i]=$line
    let "i++"
    # reading from file path
done < "<yourFullFilePath>"

stap 2: herhaal en print nu de uitvoer:

for line in "${array[@]}"
  do
    echo "$line"
  done

echo-specifieke index in array: toegang tot een variabele in array:

echo "${array[0]}"

Antwoord 10

Het volgende zal alleen de inhoud van het bestand afdrukken:

cat $Path/FileName.txt
while read line;
do
echo $line     
done

LEAVE A REPLY

Please enter your comment!
Please enter your name here

17 + 16 =

Other episodes