Программирование на Bash-скриптах: как сопоставить шаблон в строке?

Как я могу получить все это значение 7I45432ZX из следующих строк:

PW*3434*453*256*PE*UB
PO*00*NE*7I4543
2ZX**20140617
PW*3434*453*256*PE*UB
PO*00*NE*7I4543
2ZX**20140617

Это код, который я пробовал:

grep -oP 'PO.00.[A-Z][A-Z].\K[A-Z0-9_-]*' < file.txt

У меня есть этот код выше, однако, сгенерированный вывод - это только этот 7I4543 , а не весь 7I45432ZX , что, как предполагается, является моим ожидаемым результатом. Есть ли что-то, что я должен был изменить или добавить после .\K, чтобы получить все значение?

4
задан 30 July 2014 в 13:22

6 ответов

Попробуйте это:

 awk -F "*" '{ if ($1 == "PO") { lastTok = $(NF); getline; print lastTok "" $1;}}' input.txt

awk используют "*" в качестве разделителя и печати последнее поле строки, которые запускаются с ПО, сопровождаемой первым полем следующей строки.

вывод:

7I45432ZX
7I45432ZX

, Если у Вас есть файл в формате DOS, необходимо использовать команда dos2unix.

1
ответ дан 30 July 2014 в 13:22

Попробуйте следующую остроту:

$ cat file.txt | perl -e 's/\s//g && print "$_\n" for join("", <>) =~ /\*([\w\s]+)\*\*/g'
7I45432ZX
7I45432ZX

Я в основном ищу шаблон между звездой * и 2 звезды **. После того, как найденный, я просто удаляю пробелы/возвраты каретки перед печатью.

1
ответ дан 30 July 2014 в 13:22

Если Вы не хотите устанавливать Perl или что-либо еще и хочет пойти со старым добрым стандартом coomand инструменты строки, можно использовать что-то вроде:

sed '1 d
2 s/^PO\*00\*[A-Z][A-Z]\*\([A-Z0-9_-]*\)$/\1/
3 s/^\([A-Z0-9_-]*\)\*\*.*$/\1/' < file.txt

Это принимает это

  • Ваш файл содержит 3 строки. Если Ваш файл содержит 5 строк со строками 1, 3 и 5 содержащий соответствующую информацию, необходимо будет заменить 2 3 и 3 5 и добавьте 2 d и 4 d команды на дополнительных строках собой;
  • можно жить с переводом строки в выводе. Если это не хорошо для Вас, передайте вывод по каналу к tr как так: | tr -d "\n\r"

[Править]

  • sed часть также предполагает, что Вы имеете UN*X текстовые строки. Кроме того, кажется, существует спор, насколько строгий шаблоны должны быть. Я чувствую, что OP предложил определенную степень строгости. Так или иначе, sed шаблоны могут быть легко скорректированы для принятия DOS окончания строки, например, путем окончания в \r*$.
0
ответ дан 30 July 2014 в 13:22

До grep и sed:

grep -oPz '7I4543$\n^2ZX' file |sed '$!N;s/\n//'
7I45432ZX
7I45432ZX

grep шаблоны 7I4543 и 2ZX и все между ними в нескольких строках. $ в точках команды grep к концу строки и ^ точки запускаются строки.

sed соединяет каждую пару строк к одному линейному. $ точки текущая строка, N точки к следующей строке. тогда замените/удалите новую строку \n между этим строки.

-o, --only-matching
      Print only the matched (non-empty) parts of a matching line,
      with each such part on a separate output line.

-P, --perl-regexp
      Interpret PATTERN as a Perl compatible regular expression (PCRE)

-z, --null-data
      Treat the input as a set of lines, each terminated by a zero byte (the ASCII 
      NUL character) instead of a newline. Like the -Z or --null option, this option 
      can be used with commands like sort -z to process arbitrary file names.

Возможный другой grep с:

$ grep -oPz '7I4543$(^2ZX|\n)+'
$ grep -oPz '7I4543$\s^2ZX'
1
ответ дан 30 July 2014 в 13:22

Через GNU awk,

$ awk -v RS="PO" '/^\*/{gsub(/^.*\*/,"",$1); gsub(/\*.*$/,"",$2); print $1$2}' file
7I45432ZX
7I45432ZX
0
ответ дан 30 July 2014 в 13:22

Установка pcregrep:

sudo apt-get install pcregrep

и затем выполненный:

pcregrep -oM "PO.00.[A-Z][A-Z].\K[A-Z0-9_-].*\s+.*\*" < file.txt | tr -d '\n' | sed -e 's/\*\*/\n/g'

Вывод:

7I45432ZX
7I45432ZX

Вот объяснение того, что делает сценарий. В первую очередь, я должен был сделать Ваше исходное чтение сценария через переводы строки, и затем после этого оно произведет результат на двух отдельных строках, если я не заставил его записать через переводы строки также. Последняя часть сценария sed -e 's/\*\*/\n/g' помещает перевод строки после каждого разделителя согласно просьбе автором вопроса в комментарии к этому ответу.

0
ответ дан 30 July 2014 в 13:22

Другие вопросы по тегам:

Похожие вопросы: