sed не распечатывает соответствующую группу, как ожидалось - PullRequest
1 голос
/ 13 января 2020

Я ожидаю, что в моей первой группе будет только письмо , но я все равно получу di git.

Вот мой седь:
echo "AAA-TTS-MAN-M4A ,abc,blurblur" |sed -r 's/(\(-?[A-Z]+)\)\(,[a-z]{2,}\)\(,.*\)/\1\/2\/3/p'

Я ожидаю, что это только вентиляционные отверстия: AAA-TTS-MAN ,abc,blurblur

Но вместо этого он также показывает M4A, который имеет ди git.

Пожалуйста, помогите мне понять, где я неправ. Спасибо!

1 Ответ

0 голосов
/ 13 января 2020

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

sed -En 's/^([A-Z]+\b(-[A-Z]+\b)*)[^,]*((,[a-z]+)*).*/\1\3/p' file

Используйте опцию -E, чтобы уменьшить количество обратных слэшей для операторов (, ) и +. Используйте параметр -n для предотвращения неявной печати. ​​

  • Регулярное выражение привязывается к началу строки с помощью оператора ^.
  • Первая обратная ссылка должна возвращаться первое поле меньше любых лишних слов.
    • [A-Z]+\b соответствует одной или нескольким заглавным буквам, заканчивающимся границей слова.
    • (-[A-Z]+\b)* соответствует нулю или более дефисных слов.
  • [^,]* соответствует нулю или нескольким не запятым символам (эти символы будут потеряны).
  • (,[a-z]+)* соответствует нулю или большему количеству символов в нижнем регистре, которым предшествует запятая.
  • .* совпадений все оставшиеся символы в конце строки (снова потерянные).

NB. Для группировки и обратных ссылок в качестве разделителей используются парены, поэтому обратные ссылки 2 и 4 поглощаются обратными ссылками 1 и 3 соответственно.

После комментария от OP:

sed -E 's/^([A-Z]*([0-9][A-Z0-9]*)+-)+//;:a;/^[^,]*[0-9]/s/-[A-Z]*([0-9][A-Z0-9]*)+\b//;ta' file

При первой замене удаляются все слова в начале первого поля. Вторая подстановка находится в пределах al oop (поскольку каждая подстановка должна относиться к началу строки) и имеет префикс regexp, чтобы гарантировать, что подстановка влияет только на первое поле.

...