Как использовать sed для удаления последних n строк файла

Я хочу удалить несколько строк из конца файла. Можно ли это сделать с помощью sed?

Например, чтобы удалить строки с 2 по 4, я могу использовать

$ sed '2,4d' file

Но я не знаю номеров строк. Я могу удалить последнюю строку, используя

$sed $d file

но я хочу знать, как удалить n строк с конца. Пожалуйста, дайте мне знать, как это сделать, используя sed или какой-либо другой метод.

Ответ 1

Я не знаю о sed, но это можно сделать с помощью head:

head -n -2 myfile.txt

Ответ 2

Если параметр hardcoding n является опцией, вы можете использовать последовательные вызовы sed. Например, чтобы удалить последние три строки, удалите последнюю строку трижды:

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

Ответ 3

Из sed one-liners:

# delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D'   # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba'  # method 2

Кажется, это то, о чем вы ухаживаете.

Ответ 4

Смешное и простое решение для sed и tac:

n=4
tac file.txt | sed "1,$n{d}" | tac

НОТА

  • двойные кавычки " необходимы для оболочки, чтобы оценить переменную $n в команде sed. В одинарных кавычках интерполяция выполняться не будет.
  • tac cat перевернутая, смотри man 1 tac
  • {} в sed должны разделять $n & d (если нет, оболочка пытается интерполировать несуществующую переменную $nd)

Ответ 5

Используйте sed, но пусть оболочка выполняет математические расчеты с целью использования команды d, задав диапазон (для удаления последних 23 строк):

sed -i "$(($(wc -l < file)-22)),\$d" file

Чтобы удалить последние 3 строки, изнутри:

$(wc -l < file)

Дает количество строк в файле: скажем, 2196

Мы хотим удалить последние 23 строки, поэтому для левой стороны или диапазона:

$((2196-22))

Дает: 2174 Таким образом, оригинальная интерпретация sed после shell:

sed -i '2174,$d' file

Когда -i выполняет редактирование на месте, файл теперь содержит 2173 строки!

Если вы хотите сохранить его в новый файл, код:

sed -i '2174,$d' file > outputfile

Ответ 6

Для этого можно использовать head.

Используйте

$ head --lines=-N file > new_file

где N - количество строк, которые вы хотите удалить из файла.

Содержимое исходного файла минус последние N строк теперь находится в new_file

Ответ 7

Просто для полноты я хотел бы добавить свое решение. Я закончил это со стандартным ed:

ed -s sometextfile <<< $'-2,$d\nwq'

Это удаляет последние 2 строки, используя редактирование на месте (хотя он использует временный файл в /tmp!!)

Ответ 8

Для усечения очень больших файлов на самом деле у нас есть команда truncate. Он не знает о строках, но tail + wc может преобразовывать строки в байты:

file=bigone.log
lines=3
truncate -s -$(tail -$lines $file | wc -c) $file

Существует очевидное условие гонки, если файл записывается одновременно. В этом случае лучше использовать head - он подсчитывает байты с начала файла (mind disk IO), поэтому мы всегда будем усекать на границе строки (возможно, больше строк, чем ожидалось, если файл активно написан):

truncate -s $(head -n -$lines $file | wc -c) $file

Удобный однострочный лоток, если вы не выполнили попытку входа в систему, поставив пароль вместо имени пользователя:

truncate -s $(head -n -5 /var/log/secure | wc -c) /var/log/secure

Ответ 9

Это может сработать для вас (GNU sed):

sed ':a;$!N;1,4ba;P;$d;D' file

Ответ 10

С ответами здесь вы уже узнали бы, что sed - не лучший инструмент для этого приложения.

Однако я действительно думаю, что есть способ сделать это при использовании sed; идея состоит в том, чтобы добавить N строк для удержания пространства, пока вы не сможете читать, не нажимая EOF. Когда EOF попал, распечатайте содержимое пространства удержания и закройте.

sed -e '$!{N;N;N;N;N;N;H;}' -e x

Команда sed выше будет опускать последние 5 строк.

Ответ 11

В большинстве вышеприведенных ответов требуются команды/расширения GNU:

    $ head -n -2 myfile.txt
    -2: Badly formed number

Для немного более переносимого решения:

     perl -ne 'push(@fifo,$_);print shift(@fifo) if @fifo > 10;'

ИЛИ

     perl -ne 'push(@buf,$_);END{print @buf[0 ... $#buf-10]}'

ИЛИ

     awk '{buf[NR-1]=$0;}END{ for ( i=0; i < (NR-10); i++){ print buf[i];} }'

Где "10" - "n".

Ответ 12

Попробуйте выполнить следующую команду:

n = line number
tail -r file_name | sed '1,nd' | tail -r

Ответ 13

Вы можете получить общее количество строк с помощью wc -l <file> и использовать

head -n <total lines - lines to remove> <file>

Ответ 14

Это можно сделать в 3 этапа:

a) Подсчитайте количество строк в файле, который вы хотите изменить:

 n=`cat myfile |wc -l`

b) Вычтите из этого числа количество строк для удаления:

 x=$((n-3))

c) Сообщите sed удалить из этого номера строки ($x) до конца:

 sed "$x,\$d" myfile

Ответ 15

Я предпочитаю это решение,

head -$(gcalctool -s $(cat file | wc -l)-N) file

где N - количество удаляемых строк.

Ответ 16

Чтобы удалить последние 4 строки:

$ nl -b a file | sort -k1,1nr | sed '1, 4 d' | sort -k1,1n | sed 's/^ *[0-9]*\t//'   

Ответ 17

sed -n ':pre
1,4 {N;b pre
    }
:cycle
$!{P;N;D;b cycle
  }' YourFile

posix version

Ответ 18

Я придумал это, где n - количество строк, которые вы хотите удалить:

count=`wc -l file`
lines=`expr "$count" - n`
head -n "$lines" file > temp.txt
mv temp.txt file
rm -f temp.txt

Это немного круговое движение, но я думаю, что легко следовать.

  • Подсчитайте количество строк в главном файле
  • Вычтите количество строк, которые вы хотите удалить из count
  • Распечатайте количество строк, которые вы хотите сохранить и сохраните в временном файле
  • Замените основной файл временным файлом
  • Удалить временный файл

Ответ 19

Это приведет к удалению последних трех строк из file:

for i in $(seq 1 3); do sed -i '$d' file; done;

Ответ 20

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

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

Ответ 21

Для удаления последних N строк файла вы можете использовать ту же концепцию

$ sed '2,4d' file

Вы можете использовать комбо с хвостовой командой, чтобы перевернуть файл: если N равно 5

$ tail -r file | sed '1,5d' file | tail -r > file

И этот способ работает также там, где head -n -5 file не выполняется (как на Mac!).