Freebsd удалить строку в файле
как их вывести я разобрался(cat $FILE | grep -h $STR), а как удалить?
Если нужно внести изменения в сам файл, воспользуйтесь командой sed -i "/$STR/d" "$FILE". Если нужно внести изменения в сам файл, воспользуйтесь командой sed -i "/$STR/d" "$FILE".Но я вот так вношу:
Но я вот так вношу:
Плохое решение, если этот файл будет большим (больше размера канала, больше 4к)!
То часть файла будет потеряна.
Внимание: У меня под рукой нет машины с Linux. Я не использую эту ОС. Ответы я даю либо по памяти, либо мне помогает гугл. Тщательно читайте маны по тем командам и конфигурационным файлам, которые я упоминаю.
Будет потеряна не часть, а весь файл, так как вначале он будет открыт на запись оператором перенаправления ">", а, соответственно, обнулен. Если же использовать ">>" вместо ">", то содержимое файла не потеряется, но и результат достигнут не будет, поскольку отфильтрованный вывод будет просто-напросто добавлен к изначальному тексту.Если нужно внести изменения в сам файл, воспользуйтесь командой sed -i "/$STR/d" "$FILE".
на самом деле эта команда
1)создаёт временный файл.
2)записывает во временный файл исходный без некоторых строчек.
3)удаляет исходный.
4)переименовывает временный так, как был назван исходный.
ЗЫЖ потому можно так "редактировать" файлы "только для чтения".
Скоро придёт
Осень
это сложнее. зависит от числа строк для удаления. если их 1-10, то можно тупо загрузить в буфер sed, если <100, можно посчитать CRC32 и искать их, а если больше.
у мну в учебнике есть похожая задача: я просматриваю лог файл, но только новые строчки (только события, которые были впервые, например - первая попытка взлома сервера, если такое есть, то я с лёгкостью найду все попытки)
э. так вот. Медленно. Если файл большой, то проще использовать MySQL (ну так делаю я).
Скоро придёт
Осень
Если допускается, что строки после этого будут идти не в прежнем порядке, а как результат обработки sort -u, то:
sort -u process.list substract.list | sort - substract.list | uniq -u | sort -o process.list
(для большого substract.list должно быть намного быстрее, чем grep -F, особенно если он уже отсортирован)
удалить в файле только те строки, которые есть в другом файле?да, для N строк можно выполнить N sed в цикле. Но это ваще жуткие тормоза.
Скоро придёт
Осень
Если допускается, что строки после этого будут идти не в прежнем порядке, а как результат обработки sort -u, то:
sort -u process.list substract.list | sort - substract.list | uniq -u | sort -o process.list
ну. если ещё и допустить, что в исходном файле все строки разные, то вообще просто (слить, отсортировать, и удалить дубли)
Скоро придёт
Осень
Не совсем. Этот вариант покажет стороки которые есть только в одном (любом) файле. Мой - только в первом, как задано условием. Видимо, в таком, казалось бы, довольно распространённом случае, нет стандартных решений, и оптимально - простенькая программа на си
Если допускается, что строки после этого будут идти не в прежнем порядке, а как результат обработки sort -u, то:
sort -u process.list substract.list | sort - substract.list | uniq -u | sort -o process.list ну. если ещё и допустить, что в исходном файле все строки разные, то вообще просто (слить, отсортировать, и удалить дубли)
А как удалить дубли чтобы попроще и "одним махом"? Т.е. за один проход. А как удалить дубли чтобы попроще и "одним махом"? Т.е. за один проход.
Никак. Прямо на диске, или же в памяти (подгрузив с диска один раз), но проходов будет множество. Видимо, в таком, казалось бы, довольно распространённом случае
это как минимум 2 случая:
1) исключаем немного строк - решение - sed
2) исключаем много строк. решение БД наверное. или программа на си, разной степени сложности (тут много можно наворотить вообще-то).
Скоро придёт
Осень
1) исключаем немного строк - решение - sed
Тут лучше grep -vF, не придётся заморачиваться с экранированием символов, имеющих спец. значение для sed.
2) исключаем много строк. решение БД наверное. или программа на си, разной степени сложности (тут много можно наворотить вообще-то). ИМХО, лучший вариант здесь - хеш-таблица. Сначала пробегаем вычитаемый файл, заполняя таблицу. А затем поточно обрабатываем вычитаемый файл, сравнивая его с таблицей. И на C ничего писать не надо, скрипт на Lua из нескольких строк здесь даст не более 2-3% потери производительности по сравнению с C.ну. если ещё и допустить, что в исходном файле все строки разные, то вообще просто (слить, отсортировать, и удалить дубли)
А как удалить дубли чтобы попроще и "одним махом"? Т.е. за один проход.
если файл можно отсортировать, то:
$ sort -u file >otherfile
если уже отсортирован, то:
$ uniq file >otherfile
если сортировать нельзя, за один проход gnu-утилитами — никак. за четыре:
$ nl file | sort -u -k 2 | sort | cut -f 2 >otherfile
смысл:
1. пронумеровать строки.
2. отсортировать по второму полю и удалить дубликаты.
3. восстановить сортировку по номерам строк.
4. удалить номера строк.
кто придумает короче?
Писать безграмотно - значит посягать на время людей, к которым мы адресуемся, а потому совершенно недопустимо в правильно организованном обществе. © Щерба Л. В., 1957при сбоях форума см.блог
если файл можно отсортировать, то:
$ sort -u file >otherfile
если уже отсортирован, то:
$ uniq file >otherfile
если сортировать нельзя, за один проход gnu-утилитами — никак. за четыре:
$ nl file | sort -u -k 2 | sort | cut -f 2 >otherfile
смысл:
1. пронумеровать строки.
2. отсортировать по второму полю и удалить дубликаты.
3. восстановить сортировку по номерам строк.
4. удалить номера строк.
Но что делать, если я хочу удалить последнюю строку файла, и я не знаю количество строк (я знаю, что могу получить это, используя wc и несколько других приемов).
В настоящее время используется обходной путь head и в tail сочетании с wc этим. Какие-нибудь быстрые повороты здесь?
Какой ОС? У некоторых ароматов есть интересные варианты head и tail . @ Nils Я нахожусь на 'Red Hat Enterprise Linux Server версии 5.5 (Tikanga)'. Можете ли вы указать на варианты head и tail вы знаете о различных вкусах?в sed $ последняя строка, поэтому удалить последнюю строку:
Используйте sed -i '$d' <file> для редактирования файла на месте. Что было бы для удаления последних n строк, где n - любое целое число?$ за последнюю строку:
К сожалению, хотя нужно использовать более сложные методы, чтобы удалить, скажем, последние две строки. @Rob: sed '$d' file фактически не изменяет файл; он просто распечатывает содержимое файла, за исключением последней строки. Таким образом, sed '$d' file; sed '$d' file будет распечатывать содержимое файла дважды , минус последняя строка каждый раз. Эквивалент delete-the-last-two-line sed '$d' file равен is sed '$d' file | sed '$d' . Да, это не элегантно, но, конечно, это работает. Я бы сделал это за один проход с sed -n '1cat file.txt | head -n -1 > new_file.txt
Остерегайтесь, кажется, в зависимости от последней строки file.txt (если она заканчивается EOF , или \n и затем EOF ), количество строк в new_file.txt может быть таким же (как file.txt ) после этой команды (это происходит, когда нет \n ) - в любом случае, содержимое последней строки удаляется.
Также обратите внимание, что вы должны использовать второй (промежуточный) файл. Если вы переадресовали и перенаправили на тот же файл, вы удалите его.
Где это работает, это также может быть просто head -n -1 file.txt > new_file.txt . Обратите внимание, что отрицательный счет head -n доступен только для некоторых реализаций head . Например, это не работает для FreeBSD или для версии BusyBox head . @dubiousjim: Согласен, head -n -1 file.txt > new_file.txt лучше. Он работает одинаково в отношении двух моих комментариев (одинаковое количество строк и стирание в одном и том же файле). Что касается отрицательного аргумента, такие различия время от времени возникают между Unix, и они часто разочаровывают, потому что вы ожидаете, что это будет одна и та же команда целиком (и почему бы вам не - то же имя и цель!) - во всяком случае, хорошо точка. (Я использую Debian.)head --lines=-1 , Сначала я наткнулся на эту возможность в man-странице для головы в SLES11SP2-системе (coreutils-8.12-6.23.1)
tail и head являются частью coreutils -rpm (по крайней мере для систем на основе rpm).
Согласно журналу изменений coreutils, этот синтаксис поддерживается начиная с версии coreutils 5.0.1.
Плохая новость: в соответствии с man-страницей RH5 эта опция не описана
rpm -q coreutils показывает мне (на CentOS 5.8): coreutils-5.97-34.el5_8.1
Я не уверен, что RH5.5. уже имеет версию coreutils, которая ее поддерживает. Но у 5.5 все равно есть EoLed.
Мне нужно многократно удалять первую строку из огромного текстового файла, используя скрипт bash.
Прямо сейчас я использую sed -i -e "1d" $FILE - но удаление занимает около минуты.
Есть ли более эффективный способ сделать это?
@cikatomo: он обозначает встроенное редактирование - он редактирует файл с тем, что вы генерируете. Хвост НАМНОГО МЕДЛЕН, чем сед. хвосту нужно 13,5 с, седу - 0,85 с. Мой файл имеет100 МБ. MacBook Air 2013 с SSD.
-n x : Просто напечатайте последние x строки. tail -n 5 даст вам последние 5 строк ввода. + Знак рода инвертирует аргумент и сделать tail печать ничего , кроме первых x-1 строк. tail -n +1 будет печатать весь файл, tail -n +2 все, кроме первой строки и т. д.
GNU tail намного быстрее чем sed . tail также доступен на BSD, и -n +2 флаг одинаков для обоих инструментов. Проверьте справочные страницы FreeBSD или OS X для получения дополнительной информации.
Версия BSD может быть намного медленнее, чем sed , однако. Интересно, как им это удалось; tail следует просто читать файл построчно, в то время как sed выполняет довольно сложные операции, включая интерпретацию скрипта, применение регулярных выражений и тому подобное.
Примечание: вы можете испытать желание использовать
но это даст вам пустой файл . Причина в том, что redirection ( > ) происходит до того, tail как вызывается оболочкой:
- Файл усеченных оболочек $FILE
- Shell создает новый процесс для tail
- Shell перенаправляет стандартный вывод tail процесса на $FILE
- tail читает из теперь пусто $FILE
Если вы хотите удалить первую строку внутри файла, вы должны использовать:
&& Будет убедиться , что файл не будет перезаписан , когда есть проблема.
@Eddie: user869097 сказал, что это не работает, если одна строка составляет 15 МБ или больше. Пока строки будут короче, tail будут работать файлы любого размера. @Dreampuf - со страницы руководства: -n N means output the last N lines, instead of the last 10; or use +N to output lines starting with the Nth Я собирался согласиться с @JonaChristopherSahnwaldt - tail намного, намного медленнее, чем вариант sed, на порядок. Я тестирую его на файле с 500 000K строк (не более 50 символов в строке). Однако затем я понял, что использую версию tail для FreeBSD (которая по умолчанию поставляется с OS X). Когда я переключился на GNU tail, хвостовой вызов был в 10 раз быстрее, чем вызов sed (и вызов GNU sed тоже). AaronDigulla является правильным здесь, если вы используете GNU.Вы можете использовать -i для обновления файла без использования оператора «>». Следующая команда удалит первую строку из файла и сохранит ее в файл.
Я получаю ошибку: unterminated transform source string это работает каждый раз и действительно должно быть лучшим ответом! Напомним, что Mac требует предоставления суффикса при использовании sed с правками на месте. Так что запустите выше с -i.bak Просто примечание - чтобы удалить несколько строк использовать sed -i '1,2d' filename Эта версия действительно намного более читабельна и универсальна, чем tail -n +2 . Не уверен, почему это не лучший ответ.Для тех, кто работает в SunOS, отличной от GNU, поможет следующий код:
Нет, это примерно так же эффективно, как вы собираетесь получить. Вы могли бы написать программу на C, которая могла бы выполнять работу немного быстрее (меньше времени запуска и обработки аргументов), но она, вероятно, будет стремиться к той же скорости, что и sed, когда файлы становятся большими (и я предполагаю, что они велики, если это займет минуту ).
Но ваш вопрос страдает от той же проблемы, что и многие другие, в том смысле, что он предполагает решение. Если бы вы подробно рассказали нам о том, что вы пытаетесь сделать, а не о том , как , мы можем предложить лучший вариант.
Например, если это файл A, который обрабатывает какая-то другая программа B, одним из решений было бы не убрать первую строку, а изменить программу B для ее обработки по-другому.
Допустим, все ваши программы добавляют к этому файлу A, и программа B в настоящее время читает и обрабатывает первую строку перед ее удалением.
Вы могли бы перепроектировать программу B так, чтобы она не пыталась удалить первую строку, но сохранила постоянное (вероятно, основанное на файле) смещение в файле A, чтобы при следующем запуске она могла искать это смещение, обрабатывая линия там, и обновить смещение.
Затем в тихое время (полночь?) Он может выполнить специальную обработку файла A, чтобы удалить все обрабатываемые в данный момент строки и установить смещение обратно на 0.
Конечно, для программы будет быстрее открывать и искать файл, чем открывать и перезаписывать. Это обсуждение предполагает, что у вас есть контроль над программой B, конечно. Я не знаю, так ли это, но могут быть и другие возможные решения, если вы предоставите дополнительную информацию.
Руководство по FreeBSD состоит из девяти разделов. Эти разделы выглядят так:
1.General commands (Основные команды)
2.System calls and error numbers (Системные вызовы и коды ошибок)
3.The С libraries(Библиотеки С)
4.Devices and device drivers (Устройства и драйверы устройств)
5.File formats(Форматы файлов)
6.Game instructions (Инструкции к играм)
7.Miscellaneous information(Всякая всячина)
8.System maintenance commands(Команды обслуживания системы)
9.Kernel system interfaces(Системные интерфейсы ядра)
Для того чтобы читать man в конкретном разделе нужно использовать синтаксис:
man N name
Где N номер раздела справки, а name название программы
Пример:
man 4 pf
Секции страницы помощи:
NAME – имя страницы с очень кратким описанием предмета (одна строка)
SYNOPSIS – синопсис, краткий обзор
DESCRIPTION – полное описание предмета справки
ENVIRONMENT – используемые переменные окружения
EXIT STATUS – коды возврата программ
EXAMPLES – примеры использования
SEE ALSO – рекомендуемые man страницы для получения дополнительной информации
2. Основные команды для работы с файлами
Во Фре все это ФАЙЛЫ. устройства это тоже файлы:)
В UNIX существуют различные виды файлов, информация о которых содержится атрибутах файловой системы для этих файлов. Всего в UNIX существует 6 различных видов файлов:
• Обычный файл (regular file)
• Каталог (directory)
• Специальный файл устройства (special device file)
• FIFO, или именованный канал (named pipe)
• Символьная ссылка (symbol link)
• Сокет (socket)
Для фри неважно расширение. Она ориентируется на основании магии! Вернее magic numbers.
Узнать тип файла можно с помощью утилиты file:
%file /etc/rc.conf
/etc/rc.conf: ASCII text
%file /bin/sh
/bin/sh: ELF 32-bit LSB executable, Intel 80386, version 1 (FreeBSD), dynamically linked (uses shared libs), for FreeBSD 9.0 (900044), stripped
ls (list files) предназначена для просмотра содержимого каталогов и получения информации о файлах.
ls -a вывод полностью ( со скрытыми файлами и папками )
ls -l вывод в подробной форме ( с правами, размером, датами и т.д.);
ls -i выводит также inode файла
Примеры:
%ls
f1 f2 f3
%ls -la
total 12
drwxr-xr-x 2 root bos 512 16 мар 19:14 .
drwxr-xr-x 5 bos bos 512 29 апр 13:36 ..
-rw-r--r-- 2 root bos 19 16 мар 19:15 f1
-rw-r--r-- 1 root bos 0 16 мар 19:10 f2
-rw-r--r-- 1 root bos 0 16 мар 19:10 f3
pwd (print working directory) показывает текущий рабочий каталог.
%pwd
/usr/home/bos/A
cd (change directory) меняет текущий рабочий каталог.
Путь может быть относительным, а может и абсолютным(начинаться с / )
cd - перейти в домашний каталог
cd .. - подняться на каталог выше
cd
root - перейти в домашний каталог заданного пользователя
cd - - перейти в предыдущий каталог
touch меняет временные метки файла и имеет побочное действие, которое используется гораздо чаще, чем основное – если файла с указанным именем нет, создается пустой файл.
%ls -la | grep -E '[[:space:]]f.*'
-rw-r--r-- 1 bos bos 0 2 май 13:20 ft1
-rw-r--r-- 1 bos bos 0 2 май 13:20 ft2
%touch ft1
%touch ft3
%ls -la | grep -E '[[:space:]]f.*'
-rw-r--r-- 1 bos bos 0 2 май 13:22 ft1
-rw-r--r-- 1 bos bos 0 2 май 13:20 ft2
-rw-r--r-- 1 bos bos 0 2 май 13:22 ft3
rmdir удаляет только пустые каталоги.
-p удаляются и родительские каталоги целевого каталога, если они пусты.
% rmdir /tmp/test
% rmdir -p /tmp/a/b/c
cp позволяет копировать файли и каталоги (опция -r или -R).
При её использовании часто применяются шаблоны шелла. В общем случае, команда cp требует не менее двух параметров: что копировать и куда копировать.
% cp file1 dir1/
% cp -r dir1/ dir2/
mv предназначена для перемещения и переименования файлов и каталогов. При перемещении внутри одного каталога имя исходного файла/каталога меняется на новое, что эквивалентно переименованию. При перемещении внутри одного раздела (одной файловой системы) меняется только жесткая ссылка на объект и процесс перемещения происходит очень быстро. При перемещении данных между различными файловыми cистемами происходит копирование с последующим удалением источника, так что время выполнения команды зависит от объема данных.
%mv file2 file3 - переименовали файл
%mv file3 dir1/ - переместили файл в dir1
ln позволяет создавать символьные (с опцией -s) и жесткие (без опции -s) ссылки.
жесткая ссылка при удалении оригинала, данные все равно будут доступны
–s будет создана мягкая ссылка(как ярлык в винде) при удалении ярлыка с файлом ничего не случается, при удалении файла, ярлык ссылается на пустое место
%ln -s /etc/rc.conf file4
cat вывод содержимого файла
more less выводят содержимое файла с возможностью прокрутки и поиска
which для поиска программ (исполняемых файлов), ищет указанные файлы в каталогах, перечисленных в переменной окружения PATH.
whereis аналогична по действию, но ищет также среди man страниц и в каталогах с исходными текстами программ. Примеры:
% which ls
/bin/ls
% whereis ls
ls: /bin/ls /usr/share/man/man1/ls.1.gz
locate Поиск файлов по имени с помощью заранее созданной индексной БД.
/usr/libexec/locate.updatedb cоздание индексной базы
Аналог службы индексирования винды, индексировать нужно руками или по крону:)
tail выводит последние строки файла
-n выводится n строк
% tail -n 5 /var/log/messages
head выводит первые строки файла
-n выводится n строк
%head -n 5 /var/log/messages
cut вырезать из входного потока или файла фрагменты строк,
-с соответствующие определенным позициям символов в строке
-f соответствующие определенным полям, считается, что файл имеет табличную структуру (т. е. разбит на колонки)
-d указывает разделитель полей. По умолчанию табуляция
cut -d: f1,7 /etc/passwd вывести 1й и 7й столбик из файла
cut -c1-5 /etc/passwd вывести символы, в каждой строке, с первого по пятый
Paste противоположность cut, вставляет фрагменты строк и выводит на экран
-d указывает разделитель полей. По умолчанию табуляция
-s объединяет множество строк в файле в одну строку
%paste -d: b1 a1
b1:a1
b2:a2
b3:a3
b4:a4
%paste -s a1
a1 a2 a3 a4
diff выводит разницу между текстовыми файлами или оглавлениями каталогов в формате, который пригоден для последующего использования программой patch. При сравнении двоичных файлов программа diff только сообщает, совпадают или различаются между собой сравниваемые файлы.
% diff каталог1 каталог2 - сравниваем каталоги
% diff /bin/ls /usr/bin/lsvfs -сравниваем бинарные файлы
Binary files /bin/ls and /usr/bin/lsvfs differ
Патчинг проходит элементарно
% patch hello.c patch.txt
Hmm. Looks like a normal diff to me.
..
done
tr замена символов по шаблону
Заменяет маленькие буквы в файле на большие и выводит на экран, сам файл остается без изменений
tr "[:lower:]" "[:upper:]"
tee транслящия stdin в stdout c ведением лога(копированием в файл)
uniq – нахождение дублирующихся строк, если попадается повторяющаяся строка то она не будет выведена.
find осуществляет рекурсивный поиск файлов в файловой системе, не использует базы данных и переменные окружения.
Условия поиска:
-mount или -xdev – осуществлять поиск только в пределах одной физической файловой системы
-name шаблон – поиск файла по его имени
-iname шаблон – то же, но без учета регистра
-regex шаблон – то же, что и name, но шаблон – регулярное выражение
-type тип_файла – поиск файлов указанного типа
b block special
c character special
d directory
f regular file
l symbolic link
p FIFO
s socket
-user пользователь – искать файлы, принадлежащие пользователю
-group группа – искать файлы, принадлежащие группе
-atime N – искать файлы, доступ к которым был N суток назад
-mtime N – искать файлы, которые менялись N суток назад
-size N – искать файлы, размер которых N блоков
Команды:
-exec программа – выполнить указанную программу передав ей имя файла(с помощью <>)
-ok программа – то же, что exec, но с запросом подтверждения для каждого файла
Пример:
% find /usr/share -name index.html
Поиск файлов, которые модифицировались за последние 2 дня и вывод полной информации про них
% find /var/log -ctime 2 -type f -ls
Удаляем записи с сервака, старше 35 дней
% find /var/spool/asterisk/monitor -ctime +35d -exec rm -f <> \;
Читайте также: