Очистить файл до N строки

На самом деле это единственный раздел про unix на этом форуме

Модераторы: /dev/random, Модераторы разделов

Grih65kop
Сообщения: 145

Очистить файл до N строки

Сообщение Grih65kop »

Необходимо очистить файл до, например, до 5 строчки с конца.
Я представляю что можно их вывести tail -5 file, но вот как теперь очистить все кроме них.
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Очистить файл до N строки

Сообщение SLEDopit »

Grih65kop писал(а):
01.08.2010 23:09
Я представляю что можно их вывести tail -5 file, но вот как теперь очистить все кроме них.
т.е. вам нужно чтобы изменения записались в сам файл?
тогда так:

Код: Выделить всё

sed -i -e :a -e '$q;N;6,$D;ba' file
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: Очистить файл до N строки

Сообщение /dev/random »

TMP=$(mktemp)
tail -5 file > "$TMP"
cat "$TMP" > file
rm -f "$TMP"
Спасибо сказали:
Grih65kop
Сообщения: 145

Re: Очистить файл до N строки

Сообщение Grih65kop »

/dev/random писал(а):
01.08.2010 23:14
TMP=$(mktemp)
tail -5 file > "$TMP"
cat "$TMP" > file
rm -f "$TMP"

Необходимо без создания нового файла т.е. файл уже существует, нужно его имя и что бы остались его права.

SLEDopit писал(а):
01.08.2010 23:14
Grih65kop писал(а):
01.08.2010 23:09
Я представляю что можно их вывести tail -5 file, но вот как теперь очистить все кроме них.
т.е. вам нужно чтобы изменения записались в сам файл?
тогда так:

Код: Выделить всё

sed -i -e :a -e '$q;N;6,$D;ba' file


Спасибо, работает, только я не совсем понимаю. Не могли бы вы более подробно описать?
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: Очистить файл до N строки

Сообщение /dev/random »

Grih65kop писал(а):
01.08.2010 23:20
Необходимо без создания нового файла т.е. файл уже существует, нужно его имя и что бы остались его права.

У меня так и делается. Создаётся временный файл, а потом его содержимое пишется поверх старого файла, без изменения его имени и прав.

Кстати, "sed -i" тоже создаёт временный файл.
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Очистить файл до N строки

Сообщение SLEDopit »

Grih65kop писал(а):
01.08.2010 23:20
Необходимо без создания нового файла т.е. файл уже существует, нужно его имя и что бы остались его права.
Ну вообще то sed -i тоже создает новый временный файл, а потом удаляет его (:
Grih65kop писал(а):
01.08.2010 23:20
Спасибо, работает, только я не совсем понимаю. Не могли бы вы более подробно описать?
Вам принцип работы или того, что вместо 6 нужно подставлять "необходимое количество строк +1", будет достаточно? (:

upd
/dev/random писал(а):
01.08.2010 23:22
Кстати, "sed -i" тоже создаёт временный файл.
эх, долго ответ я писал.
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Grih65kop
Сообщения: 145

Re: Очистить файл до N строки

Сообщение Grih65kop »

SLEDopit писал(а):
01.08.2010 23:24
Grih65kop писал(а):
01.08.2010 23:20
Необходимо без создания нового файла т.е. файл уже существует, нужно его имя и что бы остались его права.
Ну вообще то sed -i тоже создает новый временный файл, а потом удаляет его (:
Grih65kop писал(а):
01.08.2010 23:20
Спасибо, работает, только я не совсем понимаю. Не могли бы вы более подробно описать?
Вам принцип работы или того, что вместо 6 нужно подставлять "необходимое количество строк +1", будет достаточно? (:

upd
/dev/random писал(а):
01.08.2010 23:22
Кстати, "sed -i" тоже создаёт временный файл.
эх, долго ответ я писал.

Конечно же сам принцип.
Спасибо сказали:
Grih65kop
Сообщения: 145

Re: Очистить файл до N строки

Сообщение Grih65kop »

Существует ли способ без создания временного файла? Представляю что можно считывать в массив, но это не вариант при работе с большими файлами.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5404
ОС: Gentoo

Re: Очистить файл до N строки

Сообщение /dev/random »

Grih65kop писал(а):
01.08.2010 23:46
Существует ли способ без создания временного файла? Представляю что можно считывать в массив, но это не вариант при работе с большими файлами.

В теории - да. Но его реализация на шелле будет ужасно длинной и неэффективной.
Для этого нужно:
* подсчитать объём D (в байтах) удаляемых строк
* L - объём остальной части файла
* перенести (например, с помощью dd) L байт, начиная с D, в начало файла
* обрезать файл до объёма L

На C это можно сделать достаточно эффективно, но не на шелле.
Спасибо сказали:
Аватара пользователя
SLEDopit
Модератор
Сообщения: 4823
Статус: фанат консоли (=
ОС: GNU/Debian, RHEL

Re: Очистить файл до N строки

Сообщение SLEDopit »

Grih65kop писал(а):
01.08.2010 23:25
Конечно же сам принцип.
:a - ставим метку a
N - считываем следующую строку (фактически получаем 1 строку из двух с '\n' в середине для дальнейшшей работы D)
4,$D - удаляем все до первого '\n' (подробнее о работе D)
ba - переходим к метке а и повторяем все заново

может немного коряво объяснил, но как-то так.

Grih65kop писал(а):
01.08.2010 23:46
Существует ли способ без создания временного файла?
если не секрет, чем так мешают временные файлы?
UNIX is basically a simple operating system, but you have to be a genius to understand the simplicity. © Dennis Ritchie
The more you believe you don't do mistakes, the more bugs are in your code.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current

Re: Очистить файл до N строки

Сообщение drBatty »

SLEDopit писал(а):
01.08.2010 23:24
Ну вообще то sed -i тоже создает новый временный файл, а потом удаляет его (:

как я понял, она удаляет старый файл, а временный переименовывает.
ключ -i допускает параметр - новое имя для старого файла, тогда старый файл не удалится, а переименуется.

PS: в info sed есть эмуляция tail. И как любая эмуляция, она намного медленнее.
Я всё-же проверил: получилось для первого скрипта 18.5 сек., а для второго 6.4 сек. Таким образом второй скрипт работает примерно в 3 раза быстрее. Для сравнения: tail сработала за 2.3 секунды (ага - эта задача явно не для sed, sed вообще ни в коем случае нельзя использовать, когда есть другая утилита, заточенная именно на эту задачу - что-же вы хотели, та-же tail выделяет в самом начале памяти под 10 строк, и просто читает туда данные, нам-же приходится для каждой строки удалять первую - для чего необходимо сдвинуть остальные - т.о. нам нужно не только прочитать N байт(одну строку), переместить N*10 байт! Если-бы файл был в памяти, то sed сработала-бы не в три раза, а в 11 раз медленнее! (кстати, похоже он и был в памяти(файл в 18Мб, свободно около 200), видимо для сдвига строк (D) sed применяет следующую оптимизацию: вместо того, что-бы сдвигать весть буфер, она просто считает, что после команды D буфер начинается не с первой, а со второй строки, надо исходник глянуть). В любом случае, двигать буфер на каждой строке без особой на то необходимости - плохая идея.) Проблема sed в данном случае: невозможность загружать строки в произвольное место буфера, мы можем только добавлять в конец буфера, или полностью заменить строку. С другой стороны, значительного увеличения быстродействия можно было-бы достичь другим путём: прочитать все строки, а после этого вернутся на 10 строк назад, если известна максимальная длинна строки(M), то это сделать довольно просто: посчитать все строки, а затем вернутся на M*10 байтов назад и найти десятую строчку, я, правда не знаю, чем возвращаться, разве что той-же tail с ключом -c.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
Nazyvaemykh
Сообщения: 438
Статус: Подопытный участник

Re: Очистить файл до N строки

Сообщение Nazyvaemykh »

Поправьте ссылку плз. То, что у Вас написано info sed, выдает 404.
¡ Страсть к разрушению есть творческая страсть!
Спасибо сказали: