Y at-il une commande bash qui vous permettra d’obtenir la nième ligne de STDOUT?
C'est-à-dire quelque chose qui prendrait cette
$ ls -l
-rw-r--r--@ 1 root wheel my.txt
-rw-r--r--@ 1 root wheel files.txt
-rw-r--r--@ 1 root wheel here.txt
et faire quelque chose comme
$ ls -l | magic-command 2
-rw-r--r--@ 1 root wheel files.txt
Je me rends compte que ce serait une mauvaise pratique d’écrire des scripts destinés à être réutilisés, MAIS lorsqu’on travaille quotidiennement avec Shell, il me serait utile de pouvoir filtrer mon STDOUT de cette manière.
Je réalise aussi que ce serait une commande semi-triviale à écrire (tampon STDOUT, renvoyer une ligne spécifique), mais je veux savoir s’il existe une commande standard Shell pour le faire qui serait disponible sans que je ne lâche un script en place.
En utilisant sed
, juste pour varier:
ls -l | sed -n 2p
L'utilisation de cette alternative, qui semble plus efficace puisqu'elle arrête de lire l'entrée lorsque la ligne requise est imprimée, peut générer un SIGPIPE dans le processus d'alimentation, ce qui peut générer un message d'erreur indésirable:
ls -l | sed -n -e '2{p;q}'
J'ai vu cela assez souvent que j'utilise habituellement le premier (ce qui est plus facile à taper de toute façon), bien que ls
ne soit pas une commande qui se plaint quand il reçoit SIGPIPE.
Pour une gamme de lignes:
ls -l | sed -n 2,4p
Pour plusieurs gammes de lignes:
ls -l | sed -n -e 2,4p -e 20,30p
ls -l | sed -n -e '2,4p;20,30p'
ls -l | head -2 | tail -1
Alternative à la belle tête/queue:
ls -al | awk 'NR==2'
ou
ls -al | sed -n '2p'
Par souci d'exhaustivité ;-)
code plus court
find / | awk NR==3
durée de vie plus courte
find / | awk 'NR==3 {print $0; exit}'
Vous pouvez utiliser awk:
ls -l | awk 'NR==2'
Le code ci-dessus n'obtiendra pas ce que nous voulons à cause d'une erreur unique: la première ligne de la commande ls -l est le total ligne. Pour cela, le code révisé suivant fonctionnera:
ls -l | awk 'NR==3'
Essayez cette version sed
:
ls -l | sed '2 ! d'
Il dit "supprime toutes les lignes qui ne sont pas les secondes".
Est-ce que Perl est facilement disponible?
$ Perl -n -e 'if ($. == 7) { print; exit(0); }'
Évidemment, remplacez le nombre que vous voulez par 7.
Une autre affiche suggérée
ls -l | head -2 | tail -1
mais si vous dirigez la tête dans la queue, il semble que tout ce qui va jusqu'à la ligne N soit traité deux fois.
Pipe dans la tête
ls -l | tail -n +2 | head -n1
serait plus efficace?
Oui, le moyen le plus efficace (comme l'a déjà souligné Jonathan Leffler) est d'utiliser sed avec print & stit:
set -o pipefail # cf. help set
time -p ls -l | sed -n -e '2{p;q;}' # only print the second line & quit (on Mac OS X)
echo "$?: ${PIPESTATUS[*]}" # cf. man bash | less -p 'PIPESTATUS'
Hmm
sed n'a pas fonctionné dans mon cas. Je propose:
pour les lignes "impaires" 1,3,5,7 ... ls | awk '0 == (NR + 1)% 2'
pour les lignes "paires" 2,4,6,8 ls | awk '0 == (NR)% 2'