Во всех этих ответах хранится весь исходный файл. Это ужасная идея, и она сломается на больших файлах.
Вот быстрый способ сохранить только количество выводимых строк (обратите внимание, что более эффективный 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»).
person
Adam Katz
schedule
13.10.2015
awk -f tail.awk num=10
, 10 сами по себе будут интерпретироваться как имя файла. Удачи. - person shellter   schedule 01.02.2012