Скорее всего, вы захотите что-то вроде:
... | awk -v OFS='\n' '{a[NR]=$0} END{print a[1], a[2], a[NR-1], a[NR]}'
или если вам нужно указать число и принять во внимание проницательное замечание @Wintermute о том, что вам не нужно буферизовать весь файл, что-то вроде этого - это то, что вам действительно нужно:
... | awk -v n=2 'NR<=n{print;next} {buf[((NR-1)%n)+1]=$0}
END{for (i=1;i<=n;i++) print buf[((NR+i-1)%n)+1]}'
Я думаю, что математика в этом правильная - надеюсь, вы поняли идею использовать вращающийся буфер, индексированный NR, модифицированный размером буфера и настроенный на использование индексов в диапазоне 1-n вместо 0-(n-1) .
Чтобы помочь с пониманием оператора модуля, используемого в индексации выше, вот пример с промежуточными операторами печати, чтобы показать логику по мере ее выполнения:
$ cat file
1
2
3
4
5
6
7
8
.
$ cat tst.awk
BEGIN {
print "Populating array by index ((NR-1)%n)+1:"
}
{
buf[((NR-1)%n)+1] = $0
printf "NR=%d, n=%d: ((NR-1 = %d) %%n = %d) +1 = %d -> buf[%d] = %s\n",
NR, n, NR-1, (NR-1)%n, ((NR-1)%n)+1, ((NR-1)%n)+1, buf[((NR-1)%n)+1]
}
END {
print "\nAccessing array by index ((NR+i-1)%n)+1:"
for (i=1;i<=n;i++) {
printf "NR=%d, i=%d, n=%d: (((NR+i = %d) - 1 = %d) %%n = %d) +1 = %d -> buf[%d] = %s\n",
NR, i, n, NR+i, NR+i-1, (NR+i-1)%n, ((NR+i-1)%n)+1, ((NR+i-1)%n)+1, buf[((NR+i-1)%n)+1]
}
}
$
$ awk -v n=3 -f tst.awk file
Populating array by index ((NR-1)%n)+1:
NR=1, n=3: ((NR-1 = 0) %n = 0) +1 = 1 -> buf[1] = 1
NR=2, n=3: ((NR-1 = 1) %n = 1) +1 = 2 -> buf[2] = 2
NR=3, n=3: ((NR-1 = 2) %n = 2) +1 = 3 -> buf[3] = 3
NR=4, n=3: ((NR-1 = 3) %n = 0) +1 = 1 -> buf[1] = 4
NR=5, n=3: ((NR-1 = 4) %n = 1) +1 = 2 -> buf[2] = 5
NR=6, n=3: ((NR-1 = 5) %n = 2) +1 = 3 -> buf[3] = 6
NR=7, n=3: ((NR-1 = 6) %n = 0) +1 = 1 -> buf[1] = 7
NR=8, n=3: ((NR-1 = 7) %n = 1) +1 = 2 -> buf[2] = 8
Accessing array by index ((NR+i-1)%n)+1:
NR=8, i=1, n=3: (((NR+i = 9) - 1 = 8) %n = 2) +1 = 3 -> buf[3] = 6
NR=8, i=2, n=3: (((NR+i = 10) - 1 = 9) %n = 0) +1 = 1 -> buf[1] = 7
NR=8, i=3, n=3: (((NR+i = 11) - 1 = 10) %n = 1) +1 = 2 -> buf[2] = 8
person
Ed Morton
schedule
19.02.2015
cat x | (head -n2 && tail -n2)
не работает, а(head -n2 && tail -n2) < x
работает. Мне придется немного поразмыслить, почему это так. - person Wintermute   schedule 19.02.20151 2 3
или1 2 2 3
или что-то еще? Что, если бы это было всего 2 строки, вывод был бы1 2 1 2
или1 1 2 2
или1 2
или что-то еще? - person Ed Morton   schedule 19.02.2015n=3
,n=5
иn=7
с учетом этого входного файла. - person Ed Morton   schedule 19.02.2015head && tail
надежен.head
из GNU coreutils ведет себя по-разному для каналов и обычных файлов (источник: источник), читая поблочно в одном случае, но не в другом. В зависимости от деталей реализации это кажется плохой идеей - нет гарантии, чтоhead
оставит все, что не печатает, для работы сtail
. - person Wintermute   schedule 19.02.2015