З sedвами ви можете:
sed '24q;1,5d;12,18d' <infile >outfile
... Можливо, було б більш ефективним рішенням head. Дон уже продемонстрував, як це може працювати дуже добре, але я теж пограв із цим. Щось, що ви можете зробити для вирішення цього конкретного випадку:
for n in 5 6 7 6
do head -n"$n" >&"$((1+n%2))"
done <infile >outfile 2>/dev/null
... що закликає head4 рази записувати або до, outfileабо /dev/nullзалежно від того, чи є цією ітерацією значення $nпарного чи непарного числа.
Для більш загальних випадків я співав це разом із деякими іншими речами:
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
Це можна зробити так, як:
seq 100 | somehead -1 -5 6 -7 6
... які друкує ...
6
7
8
9
10
11
19
20
21
22
23
24
Першим аргументом очікується, що це повторне підрахунок з префіксом a -, або, якщо цього не відбувається, просто a -. Якщо підрахунок передбачений, він повторить шаблон лінії, вказаний у наступних аргументах, стільки разів, скільки зазначено, і зупиниться, як тільки це зробить.
Для кожного аргументу, що випливає, він буде інтерпретувати негативне ціле число, щоб вказати кількість рядків, до якого слід записати, /dev/nullа додатне ціле число, щоб вказати кількість рядків, до яких слід записати stdout.
Отже, у наведеному вище прикладі вона друкує перші 5 рядків до /dev/null, наступні 6 до stdout, наступні 7 /dev/nullзнову і наступні 6 ще раз до stdout. Діставшись до останнього свого аргументу і повністю проїхавшись через -1повторний підрахунок, він потім виходить. Якби це був перший аргумент, -2він би повторив процес ще раз, або -як би довше, ніж міг.
Для кожного циклу аргументу цикл whileобробляється один раз. У верхній частині кожної петлі перший рядок stdinзчитується в змінну оболонки $l. Це необхідно, тому що while head </dev/null; do :; doneбуде повторюватися нескінченно - headвказує при поверненні, коли він досяг кінця файлу. Таким чином, перевірка на EOF присвячена readі printfзапише $lплюс новий рядок stdoutлише у тому випадку, якщо другий аргумент є натуральним числом.
readПеревірка ускладнює петлю трохи , тому що відразу ж після того, як інший цикл називається - forцикл , який перебирає арг , 2-$#як представлено в $nкожній ітерації батьківського whileциклу. Це означає, що для кожної ітерації перший аргумент повинен бути зменшений на одиницю від значення, вказаного в командному рядку, але всі інші повинні зберігати свої початкові значення, і тому значення $_nvar маркера віднімається від кожного, але тільки коли-небудь має a значення більше 0 для першого аргументу
Це становить основний цикл функції, але основна частина коду знаходиться вгорі і призначена для того, щоб функція могла чисто буферувати навіть трубу як вхід. Це працює, спочатку викликаючи фонове зображення, ddщоб скопіювати його в tmpfile на виході з розмірами 4 к. Штуки. Потім функція встановлює цикл утримування - який майже ніколи не повинен завершити навіть єдиний повний цикл - лише для того, щоб переконатися, що ddвін зробив принаймні одне записування у файл до того, як функція потім замінить свій stdin дескриптором файлів, пов'язаним з tmpfile і після цього відразу від’єднується файл ізrm. Це дає можливість функції надійно обробляти потік, не вимагаючи пасток або інакше для очищення - як тільки функція звільнить її претензію на fd, tmpfile перестане існувати, оскільки єдине посилання з файловою системою вже видалено.
headіtail? Якщо так, то ваше рішення майже найкраще, що ви можете зробити. Якщо вам дозволено використовувати інші програми,sedабоawkви можете дозволити кращі рішення (наприклад, з меншою кількістю викликів процесу).