Удаление строк в текстовом файле, содержащих определенную строку
Как бы я использовал sed для удаления всех строк в текстовом файле, которые содержат определенную строку?
14 ответов:
чтобы удалить строку и вывести вывод на стандартный выход:
sed '/pattern to match/d' ./infileчтобы непосредственно изменить файл:
sed -i '/pattern to match/d' ./infileчтобы непосредственно изменить файл (и создать резервную копию):
sed -i.bak '/pattern to match/d' ./infileдля пользователей Mac OS X и FreeBSD:
sed -i '' '/pattern/d' ./infile
есть много других способов удаления строк с определенной строкой, кроме
sed:AWK
awk '!/pattern/' file > temp && mv temp fileРубин (1.9+)
ruby -i.bak -ne 'print if not /test/' filePerl
perl -ni.bak -e "print unless /pattern/" fileShell (bash 3.2 и более поздние версии)
while read -r line do [[ ! $line =~ pattern ]] && echo "$line" done <file > o mv o fileGNU grep
grep -v "pattern" file > temp && mv temp fileи конечно
sed(печать обратного быстрее, чем фактическое удаление):sed -n '/pattern/!p' file
Вы можете использовать sed для замены строк в файл. Однако это кажется намного медленнее, чем использование grep для обратного во второй файл, а затем перемещение второго файла поверх оригинала.
например
sed -i '/pattern/d' filenameили
grep -v "pattern" filename > filename2; mv filename2 filenameпервая команда занимает в 3 раза больше времени на моей машине в любом случае.
вы можете использовать
ex(который является стандартным редактором на основе команд Unix):ex +g/match/d -cwq fileгде:
+выполняет данную команду Ex (man ex), как-c, который выполняетwq(запись и выход)g/match/d- Ex команда для удаления строк с заданнымmatchсм.: мощность gприведенный выше пример является POSIX-совместимым методом для редактирования файла на месте как за это сообщение на Unix.SE и спецификации POSIX для
ex.
разница с
sedэто:
sedэто Stream Эдitor, а не редактор файлов.BashFAQесли вы не любите не переносимый код, накладные расходы ввода/вывода и некоторые другие плохие побочные эффекты. Поэтому в основном некоторые параметры (например, in-place/
-i) являются нестандартные расширения FreeBSD и могут быть недоступны в других операционных системах.
я боролся с этим на Mac. Кроме того, мне нужно было сделать это с помощью переменной замены.
поэтому я использовал:
sed -i '' "/$pattern/d" $fileздесь
$fileэто файл, где требуется удаление и$patternэто шаблон, который будет соответствовать для удаления.Я выбрал
''отсюда комментарий.здесь следует отметить использование двойные кавычки in
"/$pattern/d". Переменная не будет работать, когда мы используем один двойные кавычки.
чтобы получить inplace как результат с
grepможно сделать так:echo "$(grep -v "pattern" filename)" >filename
Я сделал небольшой тест с файлом, который содержит около 345 000 строк. Путь с
grepКажется, примерно в 15 раз быстрее, чемsedметод в данном случае.Я пробовал как с настройкой LC_ALL=C, так и без нее, похоже, не изменил тайминги значительно. Строка поиска (CDGA_00004.pdbqt.ГЗ.смола) где-то в середине файла.
вот команды и тайминги:
time sed -i "/CDGA_00004.pdbqt.gz.tar/d" /tmp/input.txt real 0m0.711s user 0m0.179s sys 0m0.530s time perl -ni -e 'print unless /CDGA_00004.pdbqt.gz.tar/' /tmp/input.txt real 0m0.105s user 0m0.088s sys 0m0.016s time (grep -v CDGA_00004.pdbqt.gz.tar /tmp/input.txt > /tmp/input.tmp; mv /tmp/input.tmp /tmp/input.txt ) real 0m0.046s user 0m0.014s sys 0m0.019s
вы также можете использовать это:
grep -v 'pattern' filenameздесь
-vбудет печатать только кроме вашего шаблона (что означает инвертировать матч).
perl -i -nle'/regexp/||print' file1 file2 file3 perl -i.bk -nle'/regexp/||print' file1 file2 file3первая команда редактирует файл(ы) inplace (-i).
вторая команда делает то же самое, но сохраняет копию или резервную копию оригинального файла(ов) путем добавления .БК к именам файлов (.bk может быть изменен на что угодно).
просто в случае если кто-то хочет сделать это для точного совпадения строк, вы можете использовать
-wфлаг в grep-w для целого. То есть, например, если вы хотите удалить строки с номером 11, но сохранить строки с номером 111:-bash-4.1$ head file 1 11 111 -bash-4.1$ grep -v "11" file 1 -bash-4.1$ grep -w -v "11" file 1 111Он работает с
-fфлаг, если вы хотите исключить несколько точных моделей сразу. Если "черный список" - это файл с несколькими шаблонами на каждой строке, который вы хотите удалить из "файла":grep -w -v -f blacklist file