sed - как убрать все строки, которые не совпадают

12

У меня есть HTML-файл. Я хочу удалить все строки, которые не начинаются с <tr>.

Я старался:

cat my_file | sed $'
s/^[^tr].*//
' | sed '/^$/d'

но он удалил все строки.

Майкл Даррант
источник
3
Проще с grep.
jcbermu
1
s/^[^tr]...соответствует строкам, начинающимся с любого символа, кроме tили r. Квадратные скобки - это диапазон символов в регулярном выражении.
Питер Кордес

Ответы:

19

Попробуйте это с помощью GNU sed:

sed -n '/^<tr>/p' file

или

sed '/^<tr>/!d' file
Кир
источник
1
Я нахожу версию с !dособенно полезной, потому что она позволяет вам написать другую команду sed в выражении, тогда как pединственная печатает совпадение, но следующая команда имеет ввод без изменений.
Юрислав
9
sed -e '/^<tr>/d'

Часть между ними /является регулярным выражением. Команда dудаляет совпадающие строки.

Обновление: ой, извините, я видел, что вы сказали НЕ. Так

sed -e '/^<tr>/!d'

Где !сводит на нет смысл матча.

user3188445
источник
3

Если это должно быть sed:

sed -ni '/^<tr>/p' file

-iредактирует файл на месте, -nпредотвращает sedпечать всех строк, регулярное выражение означает совпадение со всей строкой, с которой start ( ^), <tr>и эти строки будут напечатаны ( p).

С grep:

grep -E '^<tr>' file

С -Egrep интерпретирует расширенные регулярные выражения.

С awk:

awk '/^<tr>/' file

Или чисто bash:

while IFS= read -r l; do [[ "$l" =~ ^\<tr\> ]] && echo $l; done <file

Это [[внутреннее условное выражение bashs. Мы сравниваем $lс регулярным выражением и, если оно успешно ( &&), мы печатаем строку с echo.

хаос
источник
Ваша версия в чистом виде не может процитировать "$l". И вы помещаете его в качестве первого аргумента в echoкомандной строке, поэтому у вас возникнет проблема, если он начинается с -option. (Используйте printf '%s\n' "$l"). Also, shell read`, чтобы читать по одному за раз, поэтому это очень медленно. Обработка текстовых файлов в чистом bash обычно не является хорошим выбором, если вы не знаете, что ваш файл очень маленький.
Peter Cordes
2

Самый простой и простой ответ будет:

grep '^<tr>' path/to/file 

Это распечатает файл только с теми строками, которые начинаются с, что может быть хорошо, если вы не хотите изменять файл напрямую (например, с помощью sed).

Затем, если вам нравится то, что вы видите в выводе, вы можете просто распечатать в файл с > file

В этом случае вы экономите время на резервное копирование файла, прежде чем пытаться выполнить некоторые команды.

Vato
источник