web-dev-qa-db-fra.com

Obtenir une ligne spécifique d'un fichier texte en utilisant uniquement un script Shell

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

70
GangstaGraham

sed:

sed '5!d' file

awk:

awk 'NR==5' file
147
Kent

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
15
micromoses

Vous pouvez utiliser sed -n 5p file.

Vous pouvez également obtenir une plage, par exemple, sed -n 5,10p file.

12
nomasprime

J'utilise habituellement ceci à cette fin:

sed '5q;d' file

4
faithonour

Si, par exemple, vous voulez obtenir les lignes 10 à 20 d'un fichier, vous pouvez utiliser chacune de ces deux méthodes:

head -n 20 york.txt | tail -11

ou 

sed -n '10,20p' york.txt 

p dans la commande ci-dessus signifie impression.

Voici ce que vous verrez:  enter image description here

3
Mona Jalal

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é.)

2
William Pursell

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
0
dagelf
line=5; prep=`grep -ne ^ file.txt | grep -e ^$line:`; echo "${prep#$line:}"
0
Oder

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.

0
tripleee