парсинг настроенного простого текстового файла - PullRequest
0 голосов
/ 10 ноября 2011

Мне нужно проанализировать файл со следующими отформатированными данными и получить DIRNAME для ДРУГОГО узла.

    CLASS=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=${HOME}/information/logs)
        )
      )


    OTHER=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=${HOME}/site/location)
        )
      )

    STUDENT=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=/opt/students)
        )
      )

Я должен захватить все, что содержится в поле OTHER =, например итак:

    OTHER= <whitespace> ( <to capture> ) 

и тогда я должен захватить все, что находится в DIRNAME в ДРУГОЕ = поле, вот так:

    (DIRNAME=<to capture>)

Я хотел бы сделать это своего рода надежным скриптом, который может работать в большинстве Unix-системы, кто-нибудь знает, какие инструменты командной строки я должен использовать для этого и какие регулярные выражения мне нужно, чтобы захватить данные в как я обрисовал.

Любая помощь приветствуется,

Ted

Ответы [ 3 ]

2 голосов
/ 10 ноября 2011

см. Тест ниже:

kent$  cat t
    CLASS=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=${HOME}/information/logs)
        )
      )


    OTHER=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=${HOME}/site/location)
        )
      )

    STUDENT=
     (SOURCE=
        (TYPE=FILE)
        (DEFAULT=
           (DIRNAME=/opt/students)
        )
      )

kent$  awk -F= '$1~/OTHER/{i++;print $2} $1~/DIRNAME/ && i{i=0;gsub(/\)$/,"",$2); print $2}' t

${HOME}/site/location

обратите внимание, что над строкой вывода $ {HOME} / site / location была пустая строка, это был пробел после OTHER=

1 голос
/ 10 ноября 2011

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

sed -ne '/OTHER/,/DIRNAME/{s/^[^D]*DIRNAME=\(.*\))/\1/p}' input_file
${HOME}/site/location
0 голосов
/ 10 ноября 2011

Ваши данные выглядят так, как если бы их было легко перевести в XML. Оттуда вы можете легко использовать стандартные инструменты XML, такие как XSLT, чтобы точно указать, что вы хотите извлечь.

Для этого небольшого примера подход XML, вероятно, излишний, и если вам нужно справиться, скажем, с экранированными скобками, или с вещами, которые нужно экранировать, чтобы быть правильно сформированным XML, возможно, это не стоит усилий , Но если вы хотите крепкий и портативный, я бы сказал, что это путь.

Ваши данные выглядят как S-выражения; может быть, уже есть что-то вроде xsltproc для S-выражений?

Вот краткий двухслойный Perl, который, кажется, работает для преобразования ваших тестовых данных в какой-то псевдо-XML. Я не пытался обрабатывать корневые узлы; Спросите еще раз, если вам нужна дополнительная помощь.

$ perl -pe 's{\(([^\s=]+)=|\)}{ if (defined $1) { push @tags, $1; "<$1>" } 
> else { sprintf("</%s>", pop @tags) } }ge' /tmp/data 
CLASS=
 <SOURCE>
    <TYPE>FILE</TYPE>
    <DEFAULT>
       <DIRNAME>${HOME}/information/logs</DIRNAME>
    </DEFAULT>
  </SOURCE>


OTHER=
 <SOURCE>
    <TYPE>FILE</TYPE>
    <DEFAULT>
       <DIRNAME>${HOME}/site/location</DIRNAME>
    </DEFAULT>
  </SOURCE>

STUDENT=
 <SOURCE>
    <TYPE>FILE</TYPE>
    <DEFAULT>
       <DIRNAME>/opt/students</DIRNAME>
    </DEFAULT>
  </SOURCE>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...