Awk сопоставление с образцом - PullRequest
1 голос
/ 22 сентября 2009

Я хочу напечатать

userId = 1234
userid = 12345
timestamp = 88888888
js = abc

по моим данным

messssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
<input name="userId" value="1234" type="hidden"> messsssssssssssssssssss
<input name="userid" value="12345" type="hidden"> messssssssssssssssssss
<input name="timestamp" value="88888888" type="hidden"> messssssssssssss
<input name="js" value="abc" type="hidden"> messssssssssssssssssssssssss
messssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss

Как я могу сделать это с помощью AWK (или чего-то еще)? Предположим, что мои данные хранятся в переменной "$info" (однострочные данные).

Редактировать: однострочные данные, я имею в виду, что все данные представлены следующим образом

messss...<input name="userId" value="1234" type="hidden">messsss...<input ....>messssssss

Так что я не могу использовать grep для извлечения раздела интересов.

Ответы [ 7 ]

4 голосов
/ 22 сентября 2009

Я не уверен, что понимаю ваш комментарий "однострочные данные", но если он находится в файле, вы можете просто сделать что-то вроде:

cat file
    | grep '^<input '
    | sed 's/^<input name="//'
    | sed 's/" value="/ = /'
    | sed 's/".*$//'

Вот версия cut'n'paste:

cat file | grep '^<input ' | sed 's/^<input name="//' | sed 's/" value="/ = /' | sed 's/".*$//'

Получается:

messssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
<input name="userId" value="1234" type="hidden"> messsssssssssssssssssss
<input name="userid" value="12345" type="hidden"> messssssssssssssssssss
<input name="timestamp" value="88888888" type="hidden"> messssssssssssss
<input name="js" value="abc" type="hidden"> messssssssssssssssssssssssss
messssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss

довольно счастливо в:

userId = 1234
userid = 12345
timestamp = 88888888
js = abc

grep просто извлекает нужные вам строки, а sed соответственно:

  • Скип до первой цитаты.
  • заменить раздел между именем и значением на "=".
  • удалить все после закрывающей кавычки значения (включая эту кавычку).
3 голосов
/ 22 сентября 2009

Эта часть, вероятно, должна быть комментарием к ответу Пакс, но для этой маленькой коробки она была довольно длинной. Я думаю, что «однострочные данные» означают, что в вашей переменной вообще нет новых строк? Тогда это будет работать:

echo "$info" | sed -n -r '/<input/s/<input +name="([^"]+)" +value="([^"]+)"[^>]*>[^<]*/\1 = \2\n/gp'

Примечания по интересным битам: - -n означает, что не печатать по умолчанию - мы скажем, когда печатать с этим p в конце.

  • -r означает расширенное регулярное выражение

  • /<input/ в начале гарантирует, что мы даже не потрудимся работать со строками, которые не содержат желаемый шаблон

  • То, что \n в конце, служит для того, чтобы все записи заканчивались на отдельных строках - любые оригинальные переводы строк все равно будут присутствовать, и самый быстрый способ избавиться от них - нажать '| grep. ' в конце - вы могли бы использовать некоторую магию седа, но вы не сможете понять ее через тридцать секунд после того, как наберете ее.

Я могу придумать способы сделать это в awk, но это действительно работа для sed (или perl!).

2 голосов
/ 22 сентября 2009

с использованием perl

cat file | perl -ne 'print($1 . "=" . $2 . "\n") if(/name="(.*?)".*value="(.*?)"/);'
2 голосов
/ 22 сентября 2009

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

echo "$info"|sed 's/^\(<input\( \)name\(=\)"\([^"]*\)" value="\([^"]*\)"\)\?.*/\4\2\3\2\5/'
1 голос
/ 22 сентября 2009

IMO, анализ HTML должен выполняться с помощью правильного анализатора HTML / XML. Например, в Ruby есть отличный пакет Nokogiri для анализа HTML / XML:

ruby -e '
    require "rubygems"
    require "nokogiri"
    doc = Nokogiri::HTML.parse(ARGF.read)
    doc.search("//input").each do |node|
        atts = node.attributes
        puts "%s = %s" % [atts["name"], atts["value"]]
    end
' mess.html

выдает результат, который вы ищете

0 голосов
/ 23 сентября 2009

Такие инструменты, как awk и sed, можно использовать вместе с XMLStarlet и HTML Tidy для анализа HTML.

0 голосов
/ 23 сентября 2009

AWK:

BEGIN {
  # Use record separator "<", instead of "\n".
  RS = "<"
  first = 1
}

# Skip the first record, as that begins before the first tag
first {
  first = 0
  next
}

/^input[^>]*>/ { #/
  # make sure we don't match outside of the tag
  end = match($0,/>/)

  # locate the name attribute
  pos = match($0,/name="[^"]*"/)
  if (pos == 0 || pos > end) { next }
  name = substr($0,RSTART+6,RLENGTH-7)

  # locate the value attribute
  pos = match($0,/value="[^"]*"/)
  if (pos == 0 || pos > end) { next }
  value = substr($0,RSTART+7,RLENGTH-8)

  # print out the result
  print name " = " value
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...