J'essaie d'obtenir une ligne spécifique d'un fichier texte.
Jusqu'à présent, en ligne, je n'ai vu que des choses comme sed, (je ne peux utiliser que sh-not ni bash, sed ou autre chose du genre). Je dois le faire uniquement à l'aide d'un script Shell de base.
cat file | while read line
do
#do something
done
Je sais comment parcourir les lignes, comme indiqué ci-dessus, mais si je devais simplement obtenir le contenu d'une ligne particulière
sed:
sed '5!d' file
awk:
awk 'NR==5' file
En supposant que line
est une variable qui contient le numéro de ligne requis, si vous pouvez utiliser head
et tail
, c'est très simple:
head -n $line file | tail -1
Sinon, cela devrait fonctionner:
x=0
want=5
cat lines | while read line; do
x=$(( x+1 ))
if [ $x -eq "$want" ]; then
echo $line
break
fi
done
Vous pouvez utiliser sed -n 5p file
.
Vous pouvez également obtenir une plage, par exemple, sed -n 5,10p file
.
J'utilise habituellement ceci à cette fin:
sed '5q;d' file
La manière habituelle de faire ce genre de chose est d'utiliser des outils externes. Il est absurde d'interdire l'utilisation d'outils externes lors de l'écriture d'un script Shell. Cependant, si vous ne voulez vraiment pas utiliser d’outils externes, vous pouvez imprimer la ligne 5 avec:
i=0; while read line; do test $((++i)) = 5 && echo "$line"; done < input-file
Notez que ceci imprimera la ligne logique 5. Autrement dit, si input-file
contient des suites de ligne, elles seront comptées comme une seule ligne. Vous pouvez modifier ce comportement en ajoutant -r
à la commande de lecture. (Quel est probablement le comportement souhaité.)
Facile avec Perl! Si vous voulez obtenir les lignes 1, 3 et 5 d'un fichier, dites/etc/passwd:
Perl -e 'while(<>){if(++$l~~[1,3,5]){print}}' < /etc/passwd
line=5; prep=`grep -ne ^ file.txt | grep -e ^$line:`; echo "${prep#$line:}"
En parallèle avec La réponse de William Pursell , voici une construction simple qui devrait fonctionner même dans le Bourne Shell d'origine v7 (et donc aussi dans les endroits où Bash n'est pas disponible).
i=0
while read line; do
i=`expr "$i" + 1`
case $i in 5) echo "$line"; break;; esac
done <file
Remarquez également l'optimisation de break
en dehors de la boucle lorsque nous avons obtenu la ligne que nous recherchions.