29

Как я могу отбросить последние n строк файла с помощью фильтра командной строки unix?

Это было бы своего рода противоположностью tail: tail отбрасывает первые n строк, но передает все остальное, но я хочу, чтобы команда передавала все, кроме последних n строк.

К сожалению, я не нашел ничего подобного - head тоже не помогает. РЕДАКТИРОВАТЬ: по крайней мере, в Solaris это не принимает отрицательные аргументы.

Обновление: меня больше всего интересует решение, которое работает с большими файлами, то есть с лог-файлами, где вы можете проверить, что произошло за последние минуты.

5 ответов5

34

Если у вас есть head GNU, вы можете использовать

head -n -5 file.txt

распечатать все, кроме последних 5 строк file.txt .

Если head -n принимает отрицательных аргументов, попробуйте

head -n $(( $(wc -l file.txt | awk '{print $1}') - 5 )) file.txt
5

Вот простой способ удалить последнюю строку, которая работает на BSD и т.д.

sed '$d' input.txt

Выражение гласит: «В последней строке удалите его». Другие строки будут напечатаны, так как это стандартное поведение sed .

Вы можете связать их вместе, чтобы удалить несколько строк

sed '$d' input.txt | sed '$d' | sed '$d'

По общему признанию, это немного жестко, но делает только один просмотр файла.

Вы также можете взглянуть на это, чтобы получить дополнительные ответы: https://stackoverflow.com/questions/13380607/how-to-use-sed-to-remove-last-n-lines-of-a-file

Вот одна строка, адаптированная из одного из моих любимых там:

N=10
sed -n -e ':a' -e "1,$N!{P;N;D;};N;ba"

Мне было весело расшифровывать это, и я надеюсь, что и вы тоже (: Он сканирует N строк во время сканирования, но в остальном довольно эффективен.

4
head file.txt               # first 10 lines
tail file.txt               # last 10 lines
head -n 20 file.txt         # first 20 lines
tail -n 20 file.txt         # last 20 lines
head -20 file.txt           # first 20 lines
tail -20 file.txt           # last 20 lines
head -n -5 file.txt         # all lines except the 5 last
tail -n +5 file.txt         # all lines except the 4 first, starts at line 5
2

Мне любопытно, почему вы думаете, что head не вариант

~$ man head
...
-n, --lines=[-]K
        print the first K lines instead of the first 10; 
        with the leading `-', print all but the last K lines of each file

Это, кажется, соответствует вашей цели, используя, например:

head -n -20 yourfile.txt
0

Другой способ сделать это, если tail -n не будет принимать отрицательные аргументы, это

tac file.txt | tail -n +6 | tac

Это удалит последние 5 строк

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .