У меня есть некоторый HTML, из которого я пытаюсь извлечь ссылки. Прямо сейчас файл похож на это.
website.com/path/to/file/234432517.gif" width="620">
website.com/path/to/file/143743e53.gif" width="620">
website.com/path/to/file/123473232.gif" width="620">
website.com/path/to/file/634132317.gif" width="620">
website.com/path/to/file/432432173.gif" width="620">
Я пытаюсь использовать sed для удаления " width="620">
от всех строк. Вот мой код sed:
sudo sed -i "s/\"\swidth\=\"\d+\"\>//g" output
Почему это не работает? все, что я гуглю, приводит к некоторому коду, который похож на это, но это не работает по некоторым причинам.
Поскольку Вы используете PCRE (Perl Совместимые Регулярные выражения) синтаксис и sed
не понимает, что, это использует Основные регулярные выражения (BRE) по умолчанию. Это не знает ни одного \s
ни \d
. Вы также выходите из всех видов вещей, которых не должны оставлять (ни один \=
ни \>
делают что-либо полезное), не выходя из вещей, которых действительно должны оставить (+
просто означает символ +
в BRE Вам нужно \+
для "одного или нескольких".
Это должно сделать то, в чем Вы нуждаетесь:
sed 's/" width="[0-9]\+">//g' file
Или, использование Расширенных регулярных выражений:
sed -E 's/"\s*width="[0-9]+">//g' file
Наконец, как правило Вы никогда не используете sed -i
без первого тестирования без -i
чтобы быть уверенным, это работает или, если Вы делаете, по крайней мере, используйте -i.bak
(-i
с любым текстом сделает это) создать резервное копирование.
Вот мой sed
решение:
sed -E 's/(.*)" width="[0-9]+">/\1/' filename
И как альтернатива sed
Я предлагаю использовать grep
извлечь данные из файла:
Это работало бы на Вас:
grep -o "website.*\.gif" filename
И как terdon предложенный, вот является взгляд вперед использованием решения grep
:
grep -Po '.*(?="\swidth="\d*">)' filename
Также cut
хороший вариант в Вашей ситуации:
cut -f1 -d'"' filename
Или поскольку более короткий обмен просто удаляют все после gif
sed 's/gif.*/gif/' file
.*
соответствия, которые любое количество любых символов, пока, что Вы хотите проиграть, всегда после строки, которой можно определить местоположение... и что нет никаких других экземпляров его в строке. Это соответствовало бы website.com/path/to/gif/xyz.gif" width..."
на ранее gif
, поэтому дайте нежелательные результаты.
Так как Вы записали регулярное выражение Perl, можно просто использовать Perl. Можно выпустить короткое perl
команда вместо a sed
команда. Затем Вы не должны переводить свое регулярное выражение на другой диалект, и Вы не должны воздерживаться ни от одной из удобных функций Perl.
sed -i
, использовать perl -pi -e
.sed -i.bak
, использовать perl -pi.bak -e
. (Можно использовать любой суффикс, это не должно быть .bak
.)Поскольку terdon говорит, с -i
лучше указывать суффикс, таким образом, он создает файл резервной копии, по крайней мере, если Вы не попробовали ту же команду без -i
сначала. (Это столь же верно с perl
как с sed
.)
Вот то, на что это похоже с Вашей определенной командой:
perl -pi.bak -e "s/\"\swidth\=\"\d+\"\>//g" file
При использовании одинарных кавычек вокруг поиска и заменяющего шаблона Вы не должны выходить "
символы, которые появляются в нем или отслеживают интересные правила оболочки для дважды заключенного в кавычки текста. Это поможет записать и читать. (Это не характерно для perl
; Ваш sed
команда могла быть так же упрощена.) Эта команда эквивалентна:
perl -pi.bak -e 's/"\swidth\="\d+"\>//g' file
С любой из тех команд строки в Вашем примере изменяются на:
website.com/path/to/file/234432517.gif
website.com/path/to/file/143743e53.gif
website.com/path/to/file/123473232.gif
website.com/path/to/file/634132317.gif
website.com/path/to/file/432432173.gif
Дальнейшее чтение: