55 votes

Lire n lignes à la fois en utilisant Bash

J'ai lu le help read mais qui n'ont toujours pas de sens. Je ne sais pas quelle option utiliser.

Comment puis-je lire N lignes à la fois en utilisant Bash ?

50voto

gniourf_gniourf Points 9393

Avec Bash4, vous pouvez utiliser mapfile comme ça :

while mapfile -t -n 10 ary && ((${#ary[@]})); do
    printf '%s\n' "${ary[@]}"
    printf -- '--- SNIP ---\n'
done < file

C'est pour lire 10 lignes à la fois.

43voto

Fmstrat Points 759

Bien que la réponse choisie fonctionne, il n'y a pas vraiment besoin d'un gestionnaire de fichier séparé. Il suffit d'utiliser la commande de lecture sur l'identifiant original pour que tout fonctionne bien.

Voici deux exemples, l'un avec une chaîne de caractères, l'autre avec un fichier :

# Create a dummy file
echo -e "1\n2\n3\n4" > testfile.txt

# Loop through and read two lines at a time
while read -r ONE; do
    read -r TWO
    echo "ONE: $ONE TWO: $TWO"
done < testfile.txt

# Create a dummy variable
STR=$(echo -e "1\n2\n3\n4")

# Loop through and read two lines at a time
while read -r ONE; do
    read -r TWO
    echo "ONE: $ONE TWO: $TWO"
done <<< "$STR"

L'exécution de ce qui précède comme un script produirait (la même sortie pour les deux boucles) :

ONE: 1 TWO: 2
ONE: 3 TWO: 4
ONE: 1 TWO: 2
ONE: 3 TWO: 4

30voto

Aaron Digulla Points 143830

C'est plus difficile qu'il n'y paraît. Le problème est de savoir comment conserver la poignée du fichier.

La solution consiste à créer un nouveau gestionnaire de fichier qui fonctionne comme suit stdin (handle de fichier 0) mais qui est indépendant et vous pouvez lire à partir de celui-ci selon vos besoins.

#!/bin/bash

# Create dummy input
for i in $(seq 1 10) ; do echo $i >> input-file.txt ; done

# Create new file handle 5
exec 5< input-file.txt

# Now you can use "<&5" to read from this file
while read line1 <&5 ; do
        read line2 <&5
        read line3 <&5
        read line4 <&5

        echo "Four lines: $line1 $line2 $line3 $line4"
done

# Close file handle 5
exec 5<&-

24voto

Mikhail Furlender Points 1118

Méthode la plus simple - assez explicite. Elle est similaire à la méthode fournie par @Fmstrat, à l'exception du second read se trouve avant l'instruction do .

while read first_line; read second_line
do
    echo "$first_line" "$second_line"
done

Vous pouvez l'utiliser en lui envoyant une entrée multiligne :

seq 1 10 | while read first_line; read second_line 
do
    echo "$first_line" "$second_line"
done

sortie :

1 2
3 4
5 6
7 8
9 10

18voto

naviram Points 401

C'est beaucoup plus simple ! :)

cat input-file.txt | xargs -L 10 ./do_something.sh

ou

cat input-file.txt | xargs -L 10 echo

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X