Avec sedvous pourriez faire:
sed '24q;1,5d;12,18d' <infile >outfile
... Peut-être une solution plus efficace pourrait être trouvée avec head. Don a déjà montré comment cela pouvait très bien fonctionner, mais j'ai aussi joué avec. Quelque chose que vous pourriez faire pour gérer ce cas spécifique:
for n in 5 6 7 6
do head -n"$n" >&"$((1+n%2))"
done <infile >outfile 2>/dev/null
... qui appellerait head4 fois l'écriture vers outfileou vers /dev/nullselon que la valeur de cette itération $nest un nombre pair ou impair.
Pour des cas plus généraux, j'ai bricolé cela à partir d'autres choses que j'avais déjà:
somehead()(
### call it like:
### somehead -[repeat] [-][numlines]* <infile >outfile
set -e -- "${1#-}" "$@" #-e for arg validation
r=; cd -- "${TMP:-/tmp}" #go to tmp
dd bs=4096 of="$$$$" <&4 2>&3 & #dd <in >tmpfile &bg
until [ -s "$$$$" ]; do :; done #wait while tmpfile empty
exec <"$$$$" 4<&-; rm "$$$$" #<tmpfile; rm tmpfile
[ "$3${1}0" -ne "$3${2#?}0" ] || #validate args - chk $1
shift "$(((r=-${1:--1})||1))"; shift #shift 1||2
while [ "$(((r+=(_n=1))-1))" -ne 0 ] && #while ! $rptmax &&
IFS= read -r l && # ! EOF &&
printf "%.$(($1>0?${#l}+1:0))s" "$l # ? printf do
"; do for n do [ "${n#-}" -gt 0 ] || exit #args all -[nums>0]
head "-n$((${n#-}-_n))" >&"$((n>(_n=0)?1:3))" #head -n?$1 >?[+-]
done; done #done and done
) 4<&0 3>/dev/null #4<for dd 3>for head
Cela peut faire votre chose comme:
seq 100 | somehead -1 -5 6 -7 6
... qui imprime ...
6
7
8
9
10
11
19
20
21
22
23
24
Il s'attend à ce que son premier argument soit un nombre de répétitions préfixé par un -, ou, à défaut, juste un -. Si un décompte est fourni, il répétera le modèle de ligne donné dans les arguments suivants autant de fois que spécifié et s'arrêtera dès qu'il l'aura fait.
Pour chaque argument qui suit, il interprétera un entier négatif pour indiquer un compte de lignes qui doit être écrit /dev/nullet un entier positif pour indiquer un compte de lignes qui doit être écrit stdout.
Ainsi, dans l'exemple ci-dessus, il imprime les 5 premières lignes /dev/null, les 6 suivantes stdout, les 7 suivantes /dev/nullet les 6 suivantes à nouveau stdout. Après avoir atteint le dernier de ses arguments et entièrement parcouru le -1nombre de répétitions, il se ferme ensuite. Si le premier argument avait été, -2il aurait répété le processus une fois de plus, ou si -aussi longtemps qu'il le pouvait.
Pour chaque cycle d'arg, la whileboucle est traitée une fois. En haut de chaque boucle, la première ligne de stdinest lue dans la variable shell $l. Ceci est nécessaire car while head </dev/null; do :; donese répétera indéfiniment - headindique dans son retour quand il a atteint la fin du fichier. Ainsi, la vérification par rapport à EOF est dédiée readet printfn'écrira $lplus une nouvelle ligne stdoutque si le deuxième argument est un entier positif.
La readvérification complique un peu la boucle car immédiatement après l'appel d'une autre boucle - une forboucle qui itère sur les arguments 2-$#comme représenté dans $nchaque itération de sa whileboucle parent . Cela signifie que pour chaque itération, le premier argument doit être décrémenté de un de la valeur spécifiée sur la ligne de commande, mais tous les autres doivent conserver leurs valeurs d'origine, et donc la valeur du $_nmarqueur var est soustraite de chacun, mais ne contient que valeur supérieure à 0 pour le premier argument.
Cela constitue la boucle principale de la fonction, mais la majeure partie du code est en haut et est destinée à permettre à la fonction de tamponner proprement même un tuyau en entrée. Cela fonctionne en appelant d'abord un arrière-plan ddpour copier son entrée dans un fichier tmp en sortie à des blocs de 4k par morceau. La fonction établit ensuite une boucle d'attente - qui ne devrait presque jamais terminer même un seul cycle complet - juste pour s'assurer qu'elle dda effectué au moins une seule écriture dans le fichier avant que la fonction ne remplace ensuite son stdin par un descripteur de fichier lié au fichier tmp et dissocie ensuite immédiatement le fichier avecrm. Cela permet à la fonction de traiter le flux de manière fiable sans nécessiter d'interruptions ou autrement pour le nettoyage - dès que la fonction libère sa revendication sur le fd, le fichier tmp cessera d'exister car son seul lien de système de fichiers nommé a déjà été supprimé.
headettail? Si c'est le cas, votre solution est à peu près la meilleure que vous puissiez faire. Si vous êtes autorisé à utiliser d'autres programmes,sedouawksi vous autorisez de meilleures solutions (c'est-à-dire avec moins d'appels de processus).