Отрицательные аргументы в голову / хвост

14

Варианты этого вопроса, конечно, задавались несколько раз в разных местах, но я безуспешно пытаюсь удалить последние Mстроки из файла.

Второй наиболее проголосовали ответ на этот вопрос рекомендует сделать следующее , чтобы избавиться от последней строки в файле:

head -n -1 foo.txt > temp.txt

Однако, когда я пробую это в OSX и Zsh, я получаю:

head: illegal line count -- -1

Это почему? Как я могу удалить M последние строки и в первые N строки данного файла?

Амелио Васкес-Рейна
источник
1
Посмотрите, что голова и хвост POSIX не имеют эквивалента
Стефан Шазелас
1
Какой выход head --version? Какую систему вы используете?
Jofel
@jofel head --versionвозвращает ошибку на самом деле.
Амелио Васкес-Рейна

Ответы:

20

Вы можете удалить первые 12 строк с помощью:

tail -n +13

(Это означает печать с 13-й строки.)

Некоторые реализации headкак headподдержка GNU :

head -n -12

но это не стандартно.

tail -r file | tail -n +12 | tail -r

будет работать на тех системах, которые имеют tail -r(см. также GNU tac), но является неоптимальным.

Где n1:

sed '$d' file

Вы также можете сделать:

sed '$d' file | sed '$d'

удалить 2 строки, но это не оптимально.

Ты можешь сделать:

sed -ne :1  -e 'N;1,12b1' -e 'P;D'

Но будьте осторожны, это не будет работать с большими значениями n с некоторыми sedреализациями.

С awk:

awk -v n=12 'NR>n{print line[NR%n]};{line[NR%n]=$0}'

Чтобы удалить mстроки с начала и nс конца:

awk -v m=6 -v n=12 'NR<=m{next};NR>n+m{print line[NR%n]};{line[NR%n]=$0}'
Стефан Шазелас
источник
sed 'x;1d;$d'может также использоваться для получения последних двух строк. И несколько пар Nпосле 1dмогут быть использованы, чтобы получить немного больше, хотя в этот момент это не дает никакого преимущества по сравнению с N;P;Dциклом, который вы уже рекомендовали.
mikeserv
Спасибо. Последняя команда чрезвычайно полезна. Небольшое предостережение летом: оно не работает, когда mили nесть 0. В противном случае это было бы идеально.
Амелио Васкес-Рейна
2

Вы можете использовать следующий способ для удаления первых N строк и последних M строк.

С N=5, M=7и файл test.txt:

sed -n -e "6,$(($(wc -l < test.txt) - 7))p" test.txt

Команда печатает все строки от N + 1 до LastLine-M.

Другой вариант - использовать Python:

python -c 'import sys;print "".join(sys.stdin.readlines()[5:-7]),' < test.txt
jofel
источник
1

Вы можете удалить последние M(здесь M = 100) строки из файла с помощью:

head -$(($(wc -l < foo.txt) - 100)) foo.txt > temp.txt
сделать
источник