Используя sed, определите правильную строку в текстовом файле и запишите три разные части в отдельные переменные.

У меня есть группа текстовых файлов, каждый из которых содержит один экземпляр следующей строки где-то, где "(MR #" - лучший способ определить правильную строку...

Smith, John A (MR # MR123456)

Я хотел бы получить три оператора sed, которые при запуске для данного файла заполняют следующие три переменные: Plname, Pfname и MRnum. Используя приведенный выше пример, я хотел бы, чтобы переменные в конечном итоге содержали следующее после запуска операторов sed.

Plname=Smith
Pfname=John
MRnum=MR123456

Несмотря на множество примеров sed, я новичок в этом и в настоящее время борюсь с точным синтаксисом. Спасибо за вашу помощь.


person raparks    schedule 14.08.2014    source источник
comment
Что у вас есть до сих пор?   -  person Avery    schedule 14.08.2014
comment
Если я знаю, что рассматриваемая строка является первой строкой файла, как это часто бывает, я могу получить Plname, используя следующее. Но я не могу предположить, что это всегда будет первая линия. sed -n '1 с/,.*//p' $VAR_CURRENT_FILENAME   -  person raparks    schedule 14.08.2014


Ответы (1)


Что-то вроде этого:

$ cat t
bla-bla-bla
Smith, John A (MR # MR123456)
bla-bla-bla
$ Plname="$(sed -n '/(MR #/{s/^\([^,]\+\),.*/\1/p;q}' t)"
$ Pfname="$(sed -n '/(MR #/{s/^[^,]\+,[ ]\?\([^(]\+\).*/\1/p;q}' t)"
$ MRnum="$(sed -n '/(MR #/{s/^[^(]\+(MR # \([^)]\+\).*/\1/p;q}' t)"
$ printf "Plname = %s, Pfname = %s, MRnum = %s\n" "$Plname" "$Pfname" "$MRnum"
Plname = Smith, Pfname = John A , MRnum = MR123456

Небольшое объяснение:

/(MR #/{s/^\([^,]\+\),.*/\1/p;q} — это краткая форма

/(MR #/ #1 { s/^\([^,]\+\),.*/\1/; #2 p; #3 q #4 }

  • sed будет анализировать файл построчно
  • флаг -n говорит, что sed не будет печатать каждую строку (по умолчанию это делает), потому что мы будем делать это вручную, если это необходимо
  • #1 (//) находит строку, содержащую (MR #
  • and if line matches then we do following actions:
    • #2 (s///) replaces its content by regular expression
    • #3 (p) печатает результат
    • #4 (q) останавливает обработку файла, потому что мы уже нашли то, что искали
person Slava Semushin    schedule 14.08.2014
comment
Это большая помощь, и я очень ценю это. Что бы я сделал, если бы хотел получить только Джона (не: Джона А) как Pfname? - person raparks; 14.08.2014
comment
Вам нужно изменить regexp: sed -n '/(MR #/{s/^[^,]\+,[ ]\?\([^ ]\+\).*/\1/p;q}' (на самом деле я изменил в нем только один символ). И, кстати, если мой ответ был полезен, почему бы не принять или не проголосовать за него? :) - person Slava Semushin; 14.08.2014
comment
Это фантастика. Спасибо. - person raparks; 15.08.2014