Как извлечь определенную строку в Linux?

Как извлечь определенную строку в Linux?

Я новичок в Bash, и у меня возникли трудности с получением определенной строки в моем файле ниже:

  DS*SC*S45WG*X56558*2
  NE*823*2*SC*q345w45*DT*RTD*7530SRT
  RJTROIT**20140617
  SNA**TP*55
  DS*SC*S45WG*X56558*2
  NE*17*2*SC*211*DT*DFS*75304KSRTRSHT**20140617
  RSS**TP*55
  DS*SC*S45WG*X56558*2
  NE*18*1*SC*3435*DT*PR*753SLRT
  JSRT**20140617~RSS**TP*55
  DS*SC*S45WG*X56558*1
  NE*19*1*SC*ERS*DT*DFS*753048SRY
  TSERY4654**20140617~RSS**TP*60
  DS*SC*S45WG*X56558*1
  NE*19*1*SC*FRAE*DT*ESS*753048499RYTSR**20140722
  RSS**TP*140
  DS*SC*S45WG*X56558*1
  NE*73*46464
  SD**15769
  SNA*PUI*000015769

С помощью файла, который я указал выше, я хочу получить все эти следующие данные/значения:

7530SRTRJTROIT
75304KSRTRSHT
753SLRTJSRT
753048SRYTSERY4654
753048499RYTSR

(например, те, что рядом с NE*823*2*SC*q345w45*DT*RTD). Спасибо!

решение1

Поскольку интересующие вас значения, по-видимому, разбиты на несколько строк, я бы полагался на чистое регулярное выражение Perl для сопоставления правильных шаблонов:

cat file.txt | perl -e 's/\s//g && print "$_\n" for join("", <>) =~ /\*([\w\s]+)[~]{0,1}\w{3}\*\*TP/gm'

Примечание: Я предположил, что искомые вами значения заканчиваются этим разделителем:

XXX**TPгде XXXмогло быть RSSили SNAв вашем примере.

Как это работает

  • join("", <>)создает одну строку из результата catкоманды
  • который я использую для разбора ( =~оператора) с помощью этого регулярного выражения:

    /\*([\w\s]+)[~]{0,1}\w{3}\*\*TP/gm

    Это регулярное выражение ищет строки, начинающиеся со звездочки \*и состоящие из символов [A-Za-z0-9_] (сокращение \wдля слов) и пробелов \s, возможно ~(0 или 1 раз), а затем 3 символа слова (например, RSSили SNA), две звездочки \*\*, за которыми следует TP.

    Скобки используются для фиксации только заключенного в них шаблона.

    /gmявляются модификаторами регулярных выражений, которые gвозвращают все совпадающие строки (а не только первую) и mпозволяют выполнять многострочный поиск.

  • Оператор forперебирает все результаты и вызывает для каждого найденного совпадения s/\s//g && print "$_\n".

    s/\s//gудаляет все пробелы (включая возвраты каретки) и print "$_\n"выводит конечный результат ( $_текущее значение в цикле for)

Это дает мне ожидаемые значения (без их жесткого кодирования в команде):

7530SRTRJTROIT
75304KSRTRSHT
753SLRTJSRT
753048SRYTSERY4654
753048499RYTSR

Обновлять: (чтобы включить шаблон даты)

Пожалуйста, используйте следующую команду сейчас:

cat file.txt | perl -e 'for$a(join("", <>)=~/\*([A-Z0-9\s]+?)\*\*\d{8}/g){$a=~s/\s+//g;print"$a\n"}'

решение2

Вы можете использовать catдля отображения файла и grepполучения только строк с нужными вам значениями.

например:cat myfile | grep 7530SRTRJTROIT

или чтобы получить несколько значений, можно использовать egrep, что позволяет использовать регулярные выражения:
egrep "7530SRTRJTROIT|75304KSRTRSHT|753SLRTJSRT|753048SRYTSERY4654|753048499RYTSR" myfile

Связанный контент