bash: Удаление строк из файла

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

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

vodvorezlaya
Сообщения: 11
ОС: Gentoo

bash: Удаление строк из файла

Сообщение vodvorezlaya »

Подскажите новичку.

необходимо вырезать в файле определенные строки.

как их вывести я разобрался(cat $FILE | grep -h $STR), а как удалить?

спасибо.
Спасибо сказали:
vodvorezlaya
Сообщения: 11
ОС: Gentoo

Re: bash: Удаление строк из файла

Сообщение vodvorezlaya »

KonishchevDmitry писал(а):
14.03.2008 12:38
cat "$FILE" | grep -v "$STR"



Спасибо
Спасибо сказали:
allez
Сообщения: 2223
Статус: Не очень злой админ :-)
ОС: SuSE, CentOS, FreeBSD, Windows

Re: bash: Удаление строк из файла

Сообщение allez »

Если нужно внести изменения в сам файл, воспользуйтесь командой sed -i "/$STR/d" "$FILE".
Спасибо сказали:
vodvorezlaya
Сообщения: 11
ОС: Gentoo

Re: bash: Удаление строк из файла

Сообщение vodvorezlaya »

allez писал(а):
14.03.2008 15:43
Если нужно внести изменения в сам файл, воспользуйтесь командой sed -i "/$STR/d" "$FILE".


Ок. Буду знать.

Но я вот так вношу:

cat "$FILE" | grep -v "$STR" > "$FILE"

))
Спасибо сказали:
Аватара пользователя
nesk
Сообщения: 2268
Статус: Линукссаксовец
ОС: MS Windows XP Home SP3
Контактная информация:

Re: bash: Удаление строк из файла

Сообщение nesk »

vodvorezlaya писал(а):
17.03.2008 13:55
Но я вот так вношу:

cat "$FILE" | grep -v "$STR" > "$FILE"

))


Плохое решение, если этот файл будет большим (больше размера канала, больше 4к)!
То часть файла будет потеряна.
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.

0xDEFEC8ED
Спасибо сказали:
allez
Сообщения: 2223
Статус: Не очень злой админ :-)
ОС: SuSE, CentOS, FreeBSD, Windows

Re: bash: Удаление строк из файла

Сообщение allez »

Будет потеряна не часть, а весь файл, так как вначале он будет открыт на запись оператором перенаправления ">", а, соответственно, обнулен. Если же использовать ">>" вместо ">", то содержимое файла не потеряется, но и результат достигнут не будет, поскольку отфильтрованный вывод будет просто-напросто добавлен к изначальному тексту.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: bash: Удаление строк из файла

Сообщение drBatty »

vodvorezlaya писал(а):
17.03.2008 13:55
Если нужно внести изменения в сам файл, воспользуйтесь командой sed -i "/$STR/d" "$FILE".


Ок. Буду знать.

на самом деле эта команда
1)создаёт временный файл.
2)записывает во временный файл исходный без некоторых строчек.
3)удаляет исходный.
4)переименовывает временный так, как был назван исходный.

ЗЫЖ потому можно так "редактировать" файлы "только для чтения".
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: bash: Удаление строк из файла

Сообщение Demonas666 »

А если немного усложнить задачку: удалить в файле только те строки, которые есть в другом файле?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: bash: Удаление строк из файла

Сообщение drBatty »

Demonas666 писал(а):
30.03.2010 20:27
А если немного усложнить задачку: удалить в файле только те строки, которые есть в другом файле?

это сложнее. зависит от числа строк для удаления. если их 1-10, то можно тупо загрузить в буфер sed, если <100, можно посчитать CRC32 и искать их, а если больше...
у мну в учебнике есть похожая задача: я просматриваю лог файл, но только новые строчки (только события, которые были впервые, например - первая попытка взлома сервера, если такое есть, то я с лёгкостью найду все попытки)

Лог-файл из 2362 строк обработался за 410 секунд, что вполне приемлемо для моего CPU на 400MHz.

э... так вот... Медленно. Если файл большой, то проще использовать MySQL (ну так делаю я).
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
t.t
Бывший модератор
Сообщения: 7390
Статус: думающий о вечном
ОС: Debian, LMDE

Re: bash: Удаление строк из файла

Сообщение t.t »

grep -vF?
¡иɯʎdʞ ин ʞɐʞ 'ɐнɔɐdʞǝdu qнεиж
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: bash: Удаление строк из файла

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

Demonas666 писал(а):
30.03.2010 20:27
А если немного усложнить задачку: удалить в файле только те строки, которые есть в другом файле?

Если допускается, что строки после этого будут идти не в прежнем порядке, а как результат обработки sort -u, то:

sort -u process.list substract.list | sort - substract.list | uniq -u | sort -o process.list

(для большого substract.list должно быть намного быстрее, чем grep -F, особенно если он уже отсортирован)
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: bash: Удаление строк из файла

Сообщение drBatty »

Demonas666 писал(а):
30.03.2010 20:27
удалить в файле только те строки, которые есть в другом файле?

да, для N строк можно выполнить N sed в цикле. Но это ваще жуткие тормоза.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

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

Re: bash: Удаление строк из файла

Сообщение Nazyvaemykh »

Еще можно использовать команду comm из coreutils (работает только с сортированными файлами).
¡ Страсть к разрушению есть творческая страсть!
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: bash: Удаление строк из файла

Сообщение drBatty »

/dev/random писал(а):
30.03.2010 20:43
Если допускается, что строки после этого будут идти не в прежнем порядке, а как результат обработки sort -u, то:

sort -u process.list substract.list | sort - substract.list | uniq -u | sort -o process.list

ну... если ещё и допустить, что в исходном файле все строки разные, то вообще просто (слить, отсортировать, и удалить дубли)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: bash: Удаление строк из файла

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

drBatty писал(а):
30.03.2010 20:57
ну... если ещё и допустить, что в исходном файле все строки разные, то вообще просто (слить, отсортировать, и удалить дубли)

Не совсем. Этот вариант покажет стороки которые есть только в одном (любом) файле. Мой - только в первом, как задано условием.
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: bash: Удаление строк из файла

Сообщение Demonas666 »

Видимо, в таком, казалось бы, довольно распространённом случае, нет стандартных решений, и оптимально - простенькая программа на си :)
/dev/random писал(а):
30.03.2010 20:43
Если допускается, что строки после этого будут идти не в прежнем порядке, а как результат обработки sort -u, то:
sort -u process.list substract.list | sort - substract.list | uniq -u | sort -o process.list

Допускается :) Случай гипотетический :)
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: bash: Удаление строк из файла

Сообщение Demonas666 »

drBatty писал(а):
30.03.2010 20:57
ну... если ещё и допустить, что в исходном файле все строки разные, то вообще просто (слить, отсортировать, и удалить дубли)

А как удалить дубли чтобы попроще и "одним махом"? Т.е. за один проход.
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: bash: Удаление строк из файла

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

Demonas666 писал(а):
30.03.2010 22:24
А как удалить дубли чтобы попроще и "одним махом"? Т.е. за один проход.

Никак. Прямо на диске, или же в памяти (подгрузив с диска один раз), но проходов будет множество.
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: bash: Удаление строк из файла

Сообщение drBatty »

Demonas666 писал(а):
30.03.2010 22:18
Видимо, в таком, казалось бы, довольно распространённом случае

это как минимум 2 случая:
1) исключаем немного строк - решение - sed
2) исключаем много строк. решение БД наверное... или программа на си, разной степени сложности (тут много можно наворотить вообще-то).
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: bash: Удаление строк из файла

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

drBatty писал(а):
30.03.2010 22:36
это как минимум 2 случая:
1) исключаем немного строк - решение - sed
Тут лучше grep -vF, не придётся заморачиваться с экранированием символов, имеющих спец. значение для sed.

drBatty писал(а):
30.03.2010 22:36
2) исключаем много строк. решение БД наверное... или программа на си, разной степени сложности (тут много можно наворотить вообще-то).
ИМХО, лучший вариант здесь - хеш-таблица. Сначала пробегаем вычитаемый файл, заполняя таблицу. А затем поточно обрабатываем вычитаемый файл, сравнивая его с таблицей. И на C ничего писать не надо, скрипт на Lua из нескольких строк здесь даст не более 2-3% потери производительности по сравнению с C.
Спасибо сказали:
Аватара пользователя
sash-kan
Администратор
Сообщения: 13939
Статус: oel ngati kameie
ОС: GNU
Контактная информация:

Re: bash: Удаление строк из файла

Сообщение sash-kan »

Demonas666 писал(а):
30.03.2010 22:24
drBatty писал(а):
30.03.2010 20:57
ну... если ещё и допустить, что в исходном файле все строки разные, то вообще просто (слить, отсортировать, и удалить дубли)

А как удалить дубли чтобы попроще и "одним махом"? Т.е. за один проход.
если файл можно отсортировать, то:
$ sort -u file >otherfile
если уже отсортирован, то:
$ uniq file >otherfile
если сортировать нельзя, за один проход gnu-утилитами — никак. за четыре:
$ nl file | sort -u -k 2 | sort | cut -f 2 >otherfile
смысл:
1. пронумеровать строки.
2. отсортировать по второму полю и удалить дубликаты.
3. восстановить сортировку по номерам строк.
4. удалить номера строк.

кто придумает короче?
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957
при сбоях форума см.блог
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: bash: Удаление строк из файла

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

sash-kan писал(а):
30.03.2010 23:59
если файл можно отсортировать, то:
$ sort -u file >otherfile
если уже отсортирован, то:
$ uniq file >otherfile
если сортировать нельзя, за один проход gnu-утилитами — никак. за четыре:
$ nl file | sort -u -k 2 | sort | cut -f 2 >otherfile
смысл:
1. пронумеровать строки.
2. отсортировать по второму полю и удалить дубликаты.
3. восстановить сортировку по номерам строк.
4. удалить номера строк.

кто придумает короче?

А разве под "дублями" имелись в виду не строки, присутствующие ещё и в другом файле?
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: bash: Удаление строк из файла

Сообщение drBatty »

/dev/random писал(а):
30.03.2010 22:45
Тут лучше grep -vF, не придётся заморачиваться с экранированием символов, имеющих спец. значение для sed.

я не про то...
что-то вроде

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

1{
x
s/.*/cat file2.txt/e
x
}
G
s/^([^\n]*)\n.*\1//
/dev/random писал(а):
30.03.2010 22:45
ИМХО, лучший вариант здесь - хеш-таблица.

зависит от числа строк.
таблица в M ускоряет ровно в M раз. и жрёт памяти M чисел. Если строк много, то быстрее N*log(N), где N - число строк.
/dev/random писал(а):
30.03.2010 22:45
скрипт на Lua из нескольких строк

ага. а в MySQL 1 команда SELECT.
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
drBatty
Сообщения: 8735
Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
ОС: Slackware-current
Контактная информация:

Re: bash: Удаление строк из файла

Сообщение drBatty »

sash-kan писал(а):
30.03.2010 23:59
если файл можно отсортировать, то:

это не "одним махом", а за O(M*N*log(N)) операций. здесь M длинна строк, а N их число. Операции обмена строк.
В принципе это кратчайший путь, быстрее нельзя. А для ускорения можно применить готовые 2-3 деревья. Я юзаю MySQL, если сортировать нельзя.
sash-kan писал(а):
30.03.2010 23:59
$ nl file | sort -u -k 2 | sort | cut -f 2 >otherfile

это будет работать, только не очень быстро - тут две сортировки. (а если строки длинные - то это будет совсем медленно)
http://emulek.blogspot.ru/ Windows Must Die
Учебник по sed зеркало в github

Скоро придёт
Осень
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: bash: Удаление строк из файла

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

drBatty писал(а):
31.03.2010 00:07
зависит от числа строк.
таблица в M ускоряет ровно в M раз. и жрёт памяти M чисел. Если строк много, то быстрее N*log(N), где N - число строк.

Когда вы в последний раз в реальной жизни видели статические хеш-таблицы? Сейчас в ходу динамические, которые всегда имеют ровно столько строк, сколько в них записано значений.

drBatty писал(а):
31.03.2010 00:07
ага. а в MySQL 1 команда SELECT.


lua -e 'a={}; for l in io.lines("exclude.list") do a[l]=true end; for l in io.stdin:lines() do if not a[l] then print(l) end end'

Поточно обрабатывает stdin, исключая из него всё, что содержится в файле exclude.list. Быстрее вряд ли кто сделает. И не "портит" порядок строк.
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: bash: Удаление строк из файла

Сообщение Demonas666 »

sash-kan писал(а):
30.03.2010 23:59
если файл можно отсортировать, то:
$ sort -u file >otherfile
если уже отсортирован, то:
$ uniq file >otherfile
если сортировать нельзя, за один проход gnu-утилитами — никак. за четыре:
$ nl file | sort -u -k 2 | sort | cut -f 2 >otherfile
смысл:
1. пронумеровать строки.
2. отсортировать по второму полю и удалить дубликаты.
3. восстановить сортировку по номерам строк.
4. удалить номера строк.

кто придумает короче?

тут имелось ввиду другое... Не сделать из дублей "не дубли", а полностью удалить те строки, которые повторяются. Т. е. удалить обе строки.
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: bash: Удаление строк из файла

Сообщение Demonas666 »

/dev/random писал(а):
31.03.2010 00:25
lua -e 'a={}; for l in io.lines("exclude.list") do a[l]=true end; for l in io.stdin:lines() do if not a[l] then print(l) end end'
Поточно обрабатывает stdin, исключая из него всё, что содержится в файле exclude.list. Быстрее вряд ли кто сделает. И не "портит" порядок строк.

lua я не знаю... мне проще на си :blush:
Спасибо сказали:
Demonas666
Сообщения: 25
ОС: Debian GNU/Linux

Re: bash: Удаление строк из файла

Сообщение Demonas666 »

t.t писал(а):
30.03.2010 20:42
grep -vF?

Не хотит. Хотя, если честно, не понимаю почему. Пробую так:
cat src_ | grep -vF pat_
Выводит весь src_ , включая и строки, имеющиеся в pat_
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5289
ОС: Gentoo

Re: bash: Удаление строк из файла

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

Demonas666 писал(а):
31.03.2010 05:07
Не хотит. Хотя, если честно, не понимаю почему. Пробую так:
cat src_ | grep -vF pat_
Выводит весь src_ , включая и строки, имеющиеся в pat_

man grep
Спасибо сказали:
Ответить