Удалить строки в текстовом файле, который содержит определенную строку
Как использовать sed для удаления всех строк в текстовом файле, который содержит определенную строку?
Ответы
Ответ 1
Чтобы удалить строку и распечатать вывод на стандартный вывод:
sed '/pattern to match/d' ./infile
Чтобы напрямую изменить файл - не работает с BSD sed:
sed -i '/pattern to match/d' ./infile
То же самое, но для BSD sed (Mac OS X и FreeBSD) - не работает с GNU sed:
sed -i '' '/pattern to match/d' ./infile
Чтобы напрямую изменить файл (и создать резервную копию) - работает с BSD и GNU sed:
sed -i.bak '/pattern to match/d' ./infile
Ответ 2
Есть много других способов удалить строки с определенной строкой, кроме 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
Ответ 3
Вы можете использовать sed для замены строк на месте в файле. Тем не менее, это выглядит намного медленнее, чем использование grep для инверсии во второй файл, а затем перемещение второго файла по оригиналу.
например.
sed -i '/pattern/d' filename
или
grep -v "pattern" filename > filename2; mv filename2 filename
Первая команда в 3 раза больше времени на моей машине.
Ответ 4
Легкий способ сделать это с помощью GNU sed
:
sed --in-place '/some string here/d' yourfile
Ответ 5
Вы можете рассмотреть использование ex
(который является стандартным редактором на основе команд Unix):
ex +g/match/d -cwq file
где:
-
+
выполняет данную команду Ex (man ex
), так же как -c
которая выполняет wq
(запись и выход) -
g/match/d
- команда Ex для удаления строк с данным match
, см.: Сила g
Приведенный выше пример представляет собой метод, совместимый с POSIX -c, для редактирования файла на месте согласно этому посту в спецификациях Unix.SE и POSIX для ex
.
Разница с sed
том, что:
sed
- это S- tream ED itor, а не редактор файлов. BashFAQ
Если вы не наслаждаетесь непереносимым кодом, накладными расходами ввода/вывода и некоторыми другими плохими побочными эффектами. Таким образом, в основном некоторые параметры (например, на месте /-i
) являются нестандартными расширениями FreeBSD и могут быть недоступны в других операционных системах.
Ответ 6
Я боролся с этим на Mac. Плюс, мне нужно было сделать это с помощью замены переменных.
Поэтому я использовал:
sed -i '' "/$pattern/d" $file
где $file
- файл, в котором требуется удаление, а $pattern
- шаблон, который необходимо сопоставить для удаления.
Я выбрал ''
из этого комментария.
Здесь следует отметить использование двойных кавычек в "/$pattern/d"
. Переменная не будет работать, когда мы используем одинарные кавычки.
Ответ 7
Я сделал небольшой тест с файлом, который содержит приблизительно 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
Ответ 8
Чтобы получить результат, подобный inplace с помощью grep
, вы можете сделать это:
echo "$(grep -v "pattern" filename)" >filename
Ответ 9
Вы также можете использовать это:
grep -v 'pattern' filename
Здесь -v
будет печатать только ваш шаблон (это означает инвертированное совпадение).
Ответ 10
SED:
AWK:
GREP:
Ответ 11
perl -i -nle'/regexp/||print' file1 file2 file3
perl -i.bk -nle'/regexp/||print' file1 file2 file3
Первая команда редактирует файл inplace (-i).
Вторая команда выполняет то же самое, но сохраняет копию или резервную копию исходного файла (ов), добавляя.bk к именам файлов (.bk можно изменить на что угодно).
Ответ 12
echo -e "/thing_to_delete\ndd\033:x\n" | vim file_to_edit.txt
Ответ 13
cat filename | grep -v "pattern" > filename.1
mv filename.1 filename
Ответ 14
На всякий случай, если кто-то захочет сделать это для точного соответствия строк, вы можете использовать флаг -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
Ответ 15
$ git ls-files -o -c --exclude-standard > /tmp/c; git ls-files -d > /tmp/d; grep -vf /tmp/d /tmp/c