J'essaie d'obtenir une ligne spécifique à partir d'un fichier texte.
Jusqu'à présent, en ligne, je n'ai vu que des trucs comme sed, (je ne peux utiliser que sh -not bash ou sed ou quelque chose comme ça). Je dois le faire uniquement en utilisant 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 que faire si j'ai juste besoin d'obtenir le contenu d'une ligne particulière
cat
ça va maissed
pas? Ça n'a aucun sens.cat
. Aw ... mignoncat
!Réponses:
sed:
awk:
la source
5!d
signifie supprimer toutes les lignes sauf 5. shell var est possible, vous avez besoin de guillemets doubles.sed -n 5p
cela semble plus logique à retenir pour les débutants, car-n
signifie "pas de sortie par défaut" etp
signifie "impression", et il n'y a pas de mention potentiellement déroutante de la suppression (lorsque les gens parlent de fichiers, la suppression de lignes a tendance à signifie quelque chose de différent).-n '5p'
fonctionne aussi pour ce problème. La différence ici est que5!d
vous pouvez ajouter-i
pour réécrire la modification dans le fichier. cependant, avec-n 5p
vous devezsed -n '5p' f > f2&& mv f2 f
encore une fois, pour cette question, je suis d'accord avec votre opinion.En supposant
line
qu'une variable contient votre numéro de ligne requis, si vous pouvez utiliserhead
ettail
, alors c'est assez simple:Sinon, cela devrait fonctionner:
la source
-eq
comparaison concerne les entiers, elle veut donc un numéro de ligne, pas un contenu de ligne ($line
). Cela doit être corrigé en définissant par exemplewant=5
avant la boucle, puis en utilisant la-eq
comparaison sur$want
. [déplacé d'une modification rejetée]Vous pourriez utiliser
sed -n 5p file
.Vous pouvez également obtenir une gamme, par exemple
sed -n 5,10p file
.la source
Meilleure méthode de performance
Parce que
sed
cesse de lire toutes les lignes après la 5eMise à jour de l'expérience de M. Roger Dueck
la source
sed -n 5q
sed
arrête de lire les lignes après la 5ème.sed -n 1p /usr/share/dict/words
et ensed '1q;d' /usr/share/dict/words
utilisant latime
commande; le premier a pris 0,043 s, le second seulement 0,002 s, donc utiliser «q» est définitivement une amélioration des performances!Si par exemple vous souhaitez obtenir les lignes 10 à 20 d'un fichier, vous pouvez utiliser chacune de ces deux méthodes:
ou
p
dans la commande ci-dessus représente l'impression.Voici ce que vous verrez:
la source
La manière standard de faire ce genre de chose est d'utiliser des outils externes. Interdire l'utilisation d'outils externes lors de l'écriture d'un script shell est absurde. Cependant, si vous ne voulez vraiment pas utiliser d'outils externes, vous pouvez imprimer la ligne 5 avec:
Notez que cela imprimera la ligne logique 5. Autrement dit, si
input-file
contient des continuations de ligne, elles seront comptées comme une seule ligne. Vous pouvez modifier ce comportement en ajoutant-r
à la commande de lecture. (Ce qui est probablement le comportement souhaité.)la source
$((++i))
semble être un bashisme; si l'OP est limité dans l'utilisation d'outils externes, je ne suppose pas qu'ils auront accès à plus qu'une plaine/bin/sh
++
incréments est spécifiquement marquée comme facultative).$((i+=1))
fonctionne dans Dash, aussi.$(($i+1))
est la solution de contournement simple à laquelle je pensais.En parallèle avec la réponse de William Pursell , voici une construction simple qui devrait fonctionner même dans le shell Bourne v7 original (et donc aussi dans les endroits où Bash n'est pas disponible).
Remarquez également l'optimisation pour
break
sortir de la boucle lorsque nous avons obtenu la ligne recherchée.la source
Je n'ai particulièrement aimé aucune des réponses.
Voici comment je l'ai fait.
la source
Facile avec perl! Si vous voulez récupérer les lignes 1, 3 et 5 d'un fichier, dites / etc / passwd:
la source
seq 5 | perl -ne 'print if $. ~~ [1, 4, 5]'
mais le smartmatch est expérimental et son utilisation est déconseilléela source
sed -n 5p
, qui, bien sûr, peut toujours être optimisé pour quelque chose commesed -n '5!d;p;q'