it-roy-ru.com

Удалить строки в текстовом файле, которые содержат определенную строку

Как бы я использовал sed, чтобы удалить все строки в текстовом файле, которые содержат определенную строку?

1461
A Clockwork Orange

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

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
2251
SiegeX

Есть много других способов удалить строки с определенной строкой, кроме sed:

AWK

awk '!/pattern/' file > temp && mv temp file

Рубин (1,9+)

Ruby -i.bak -ne 'print if not /test/' file

Perl

Perl -ni.bak -e "print unless /pattern/" file

Shell (Баш 3.2 и позже)

while read -r line
do
  [[ ! $line =~ pattern ]] && echo "$line"
done <file > o
mv o file

GNU grep

grep -v "pattern" file > temp && mv temp file

И, конечно, sed (обратная печать выполняется быстрее, чем фактическое удаление):

sed -n '/pattern/!p' file
568
kurumi

Вы можете использовать sed для замены строк в файле. Тем не менее, это кажется намного медленнее, чем использование grep для инверсии во второй файл, а затем перемещение второго файла поверх оригинала.

например.

sed -i '/pattern/d' filename      

или же

grep -v "pattern" filename > filename2; mv filename2 filename

В любом случае, первая команда на моей машине занимает в три раза больше времени.

204
slashdottir

Самый простой способ сделать это с помощью GNU sed:

sed --in-place '/some string here/d' yourfile
58
Kevin Nguyen

Вы можете рассмотреть возможность использования 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 - это S tream ED, а не редактор файлов.BASFAQ

Если вам не нравится непереносимый код, издержки ввода/вывода и некоторые другие плохие побочные эффекты. Поэтому в основном некоторые параметры (например, на месте/-i) являются нестандартными расширениями FreeBSD и могут быть недоступны в других операционных системах.

27
kenorb

Я боролся с этим на Mac. Плюс мне нужно было сделать это с помощью замены переменных.

Поэтому я использовал:

sed -i '' "/$pattern/d" $file

где $file - это файл, в котором требуется удаление, а $pattern - шаблон, который необходимо сопоставить для удаления.

Я выбрал '' из этого комментария .

Здесь следует отметить использование двойных кавычек в "/$pattern/d". Переменная не будет работать, когда мы используем одинарные кавычки.

13
Aniket Sinha

Чтобы получить такой же результат с помощью grep, вы можете сделать это:

echo "$(grep -v "pattern" filename)" >filename
12
Jahid

Я сделал небольшой тест с файлом, который содержит примерно 345 000 строк. В этом случае путь с grep примерно в 15 раз быстрее, чем с методом sed.

Я пробовал как с настройкой LC_ALL = C, так и без нее, кажется, что изменения времени существенно не изменились. Строка поиска (CDGA_00004.pdbqt.gz.tar) находится где-то посередине файла.

Вот команды и время:

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
11
Jadzia

Вы также можете использовать это:

 grep -v 'pattern' filename

Здесь -v будет печатать только ваш шаблон (что означает инвертированное совпадение).

9
Bhuvanesh
8
Oleg Mazko

echo -e "/thing_to_delete\ndd\033:x\n" | vim file_to_edit.txt

2
Shizzmo
Perl -i    -nle'/regexp/||print' file1 file2 file3
Perl -i.bk -nle'/regexp/||print' file1 file2 file3

Первая команда редактирует файл (ы) на месте (-i).

Вторая команда делает то же самое, но сохраняет копию или резервную копию исходного файла (ов), добавляя .bk к именам файлов (.bk можно изменить на что угодно).

2
Kjetil S.
cat filename | grep -v "pattern" > filename.1
mv filename.1 filename
0
Andrey Izman

На всякий случай, если кто-то захочет сделать это для точного соответствия строк, вы можете использовать флаг -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
0
FatihSarigol