Все эти ответы хранят исходный файл весь .Это ужасная идея, и она сломается для больших файлов.
Вот быстрый способ сохранить только количество строк, которые должны быть выведены (обратите внимание, что более эффективный tail
всегда будет быстрее, потому что он не читаетвесь исходный файл!):
awk -vt=10 '{o[NR%t]=$0}END{i=(NR<t?0:NR);do print o[++i%t];while(i%t!=NR%t)}'
более разборчиво (и с меньшим кодом гольфа ):
awk -v tail=10 '
{
output[NR % tail] = $0
}
END {
if(NR < tail) {
i = 0
} else {
i = NR
}
do {
i = (i + 1) % tail;
print output[i]
} while (i != NR % tail)
}'
Объяснение разборчивого кода:
При этом используется оператор по модулю для хранения только нужного количества элементов (переменная tail
).При разборе каждой строки она сохраняется поверх более старых значений массива (поэтому строка 11 сохраняется в output[1]
).
В разделе END
переменная приращения i
устанавливается равной нулю (еслиу нас меньше желаемого количества строк) или еще количество строк, которое говорит нам, с чего начать вызывать сохраненные строки.Затем мы печатаем сохраненные строки по порядку.Цикл заканчивается, когда мы возвращаемся к этому первому значению (после того, как мы его напечатали).
Вы можете заменить строфу if
/ else
(или троичное предложение в моем примере с игрой в гольф) просто с i = NR
, если вам не нужны пустые строки для заполнения запрошенного числа (echo "foo" |awk -vt=10 …
будет иметь девять пустых строк перед строкой "foo").