Я новичок в 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