помилка sed: "недійсна посилання \ 1 на RHS команди` s "


103

Я виконую кілька команд заміни як ядро кольорового сценарію для maven . Одна з sedкоманд використовує регулярний вираз, який працює в командній оболонці, як обговорювалося тут . Поточну (не працює) реалізацію можна знайти тут .

Коли я включаю один із варіантів команди в сценарій, відбувається інша поведінка:

Варіант 1:

$ sed -re "s/([a-zA-Z0-9./\\ :-]+)/\1/g"

Адаптовано до сценарію:

-re "s/WARNING: ([a-zA-Z0-9./\\ :-]+)/${warn}WARNING: \1${c_end}/g" \

Помилка: оболонка виводить ту саму інформацію, як і я $ sed. Дивно !?


Варіант 2:

$ sed -e "s/\([a-zA-Z0-9./\\ :-]\+\)/\1/g"

Адаптовано до сценарію:

-e "s/WARNING: \([a-zA-Z0-9./\\ :-]\+\)/${warn}WARNING: \1${c_end}/g" \

Помилка:

sed: -e вираз №7, char 59: невірне посилання \ 1 на RHS команди `s '


10
У моєму випадку я поєднав -i(редагувати на місці варіант) з -re, в результаті чого -ire(таким чином, що -iспоживав reфрагмент як його SUFFIXаргумент, а значить, розширений режим регулярного вираження не був включений); змінивши її, щоб -i -reвиправити проблему.
Джанака Бандара

Помітно також помітити, що до одиничних 'і подвійних лапок "трактуються дещо по-різному, особливо при тлумаченні $vars. Наприклад: sudo sh -c "sed -r -i 's/(^.+_supplicant.conf)/\1${MTXT}/' /etc/network/interfaces"працює, але: sudo sh -c 'sed -r -i "s/(^.+_supplicant.conf)/\1${MTXT}/" /etc/network/interfaces'ні.
not2qubit

Відповіді:


51

Чи не потрібно насправді захоплювати, щоб це працювало? тобто для варіанту 2:

-r -e "s/WARNING: (\([a-zA-Z0-9./\\ :-]\+\))/${warn}WARNING: \1${c_end}/g" \

(Примітка: не перевірено)

Без аргументу -r зворотні посилання (наприклад, \ 1) не працюватимуть.


42
Для -rзворотного посилання на роботу, здається, необхідна опція sed. Наприклад, sed -e 's/([[:digit:]])/is a digit/'працює, але sed -e 's/([[:digit:]])/\1 is a digit/створює оригінальну помилку без -rsed. ПРИМІТКА: Перше виклик sed шукає буквальне значення (<digit>)і не є групою захоплення.
Ендрю Фаланга

Коментар нижче відповіді - це насправді відповідь. Можливо, ви можете відредагувати свою відповідь, щоб відобразити її.
miroxlav

@AndrewFalanga ви мали б розмістити свій коментар як відповідь
sanmai

2
Не забувайте, що моя помилка полягала в тому, щоб використовувати -ireзамість використання -ri. Питання замовлення :-)
m3nda

54

Ця помилка є загальною для дужок, які не уникнути. Втечі від них і спробуйте ще раз.


Наприклад:

/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n(.)/\1/g

Потрібно уникати зворотних нахилів перед кожними дужками:

/^$/b
:loop
$!{
N
/\n$/!b loop
}
s/\n\(.\)/\1/g

6
Увага, якщо ви користуєтеся, -rвам не доведеться уникати дужок.
qräbnö

13

Якщо опція -r/ --regexp-extendedне надана, тоді дужки, що захоплюють, повинні бути уникнуті.


5

Вам потрібно втекти /після.

sed -e "s/\([a-zA-Z0-9.\/\\ :-]\+\)/\1/g"

Або якщо ви не хочете турбуватися про втечу, скористайтеся |

sed -e "s|\([a-zA-Z0-9./\\ :-]\+\)|\1|g"

Редагувати:

sed -e "s|WARNING: \([a-zA-Z0-9.-/\\ :]+\)|${warn}WARNING: \1${c_end}|g"

Звучить розумно. Але це не працює в контексті сценарію.
JJD

Вибачте. Редагування призводить до помилки: sed: -e expression #7, char 58: Invalid range end. Відповідь @Denis працює.
JJD

2
Добре, тоді +1 для відповіді
@Denis
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.