Сед-заменяющий узор - PullRequest
       4

Сед-заменяющий узор

0 голосов
/ 24 марта 2012

У меня есть код ниже:

<td nowrap="nowrap" width="74">
<p align="center">server1</p>
</td>
<td nowrap="nowrap" width="74">
<p align="center">server2</p>
</td>

и т. Д. Я хочу получить вывод в виде:

<td nowrap="nowrap" width="74">server1</td>
<td nowrap="nowrap" width="74">server2</td>

Какой должен быть мой подход? Скажем, например, файл является сервером.html Я сделал что-то вроде этого:

sed "s/<p align="center">*</p>/*/" -i server.html

Но это не работает.

Ответы [ 5 ]

2 голосов
/ 24 марта 2012

Это ваша командная строка ...

sed "s/<p align="center">*</p>/*/" -i server.html

Проблемы:

  1. Вы указываете свои команды перед опциями, а не отождествляете команду с -e вариант.(Не уверен, что в сознании AIX есть sed.)
  2. Вы не сопоставляете текст с допустимым регулярным выражением.
  3. Закрывающий абзац имеет косую черту без отступа, которая рассматривается как разделитель.
  4. Ваша замещающая строка - просто звездочка.

Я бы не использовал sed для этого.Хотя вы, возможно, сможете придумать непонятный, нечитаемый скрипт для обработки этого с помощью GNU sed, он, вероятно, не будет переносимым, и вы не сможете прочитать его через 30 минут после его написания, если выне очень хорошо знакомы с sed и регулярными выражениями.

Вы можете вывести что-то эквивалентное тому, что вы просите, с помощью этого:

sed '/<p/s#<[^>]*>##g' server.html

Обычно возникают проблемы при обработке HTML с помощью регулярных выражений, но еслиЕсли вы работаете только с гарантированно предсказуемым текстом, AWK может быть для вас разумным решением.

#!/usr/bin/awk -f

/^<td/ { line=$0; }
/^<p/ { gsub(/<[^>]*>/,""); line=line $0; }
/^<\/td/ { print line $0; }

Обратите внимание, что это не самый элегантный сценарий awk, который можно написать;все написано более полно, чем нужно, чтобы вы могли видеть тип сопоставления с шаблоном, как обычно, чтобы вы могли настроить его для соответствия другому HTML.

Альтернатива:

#!/usr/bin/awk -f

BEGIN { ORS=""; }
/^<p/ { gsub(/<[^>]*>/,""); }
{ print; }
/^<\/td/ { printf("\n"); }

Другая вещь, на которую вы могли бы обратить внимание, это изменение поведения <p> внутри <td> с использованием CSS.

2 голосов
/ 24 марта 2012

Еще раз, кто-то анализирует HTML с помощью регулярных выражений ... Ну, похоже, следующая команда работает с конкретным примером, который вы опубликовали:

sed -re 's/<p align="center">(.*?)<\/p>/\1/g'

Тем не менее, он сломается, если что-нибудь изменится, подумайте об использовании HTML-парсера.

РЕДАКТИРОВАТЬ: без регулярного выражения, с тем же результатом можно сделать следующее:

sed -e 's/<p align="center">//g' -e 's/<\/p>//g'

Но это даже грязнее, чем первый.

2 голосов
/ 24 марта 2012

Когда вы используете регулярные выражения с sed, вы можете ссылаться на X-й совпадающий блок () с \X

Кроме того, со всеми этими косыми чертами в вашем выражении я бы использовал | в качестве разделителя sed, чтобы сделать выражение немного менее непрозрачным.

sed -e "s|<p align=\"center\">\(.*\)</p>|\1|" server.html
0 голосов
/ 24 марта 2012

Это может работать для вас:

sed '/^<td nowrap="nowrap" width="74">$/{N;N;s/\n[^>]*>\([^<]*\)<\/p>\n/\1/}' file
<td nowrap="nowrap" width="74">server1</td>
<td nowrap="nowrap" width="74">server2</td>
0 голосов
/ 24 марта 2012

Написание регулярного выражения для управления HTML - не лучший способ. Вы должны заглянуть в библиотеку HTML-разбора и написать код для преобразования HTML-кода после его анализа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...