Intereting Posts
Ограничения / etc / profile в Gnome Какова реальная точка опции -f на rm? Ошибка при использовании команды passwd – Синтаксическая ошибка не удалось запустить темноту на малине pi Скопируйте файлы автоматически в пункт назначения сразу после создания Где применять xmodmap для системного использования? Обновите 32-разрядную установку RHEL до 64-разрядной версии sudo: nocorrect: команда не найдена Правильная настройка для многократной загрузки Как перестроить диск на логическом томе с минимальным временем обнуления Создайте один PDF-файл из нескольких (выбранных) изображений Попытка перенаправить <enter> и второй ответ на скрипт linux shell Манипуляция клавишей X и указателем захватывается в командной строке Как добавить следующий статический адрес маршрута в / etc / sysconfig / network-scripts / route-eth0, чтобы сделать его постоянным? Показывать элемент в контекстном меню только для определенного типа файлов с помощью Nautilus-Actions Configuration Tool

Интерпретировать интерполированную переменную как литеральную строку в регулярном выражении Perl

Я использую perl для раскрашивания согласованной строки

 MATCH=aaa printf "aaa\n/dev/aaa\nccc\n" | perl -pe "s/($MATCH)/\e[1;31m\1\e[0m/g" 

Это работает хорошо, пока я не попытаюсь сопоставить строку, содержащую специальные символы, например

 MATCH=/dev/ printf "aaa\n/dev/aaa\nccc\n" | perl -pe "s/($MATCH)/\e[1;31m\1\e[0m/g" 

Причина в том, что когда bash заменяет $MATCH , perl получает следующее выражение:

 perl -pe "s/(/dev/)/\e[1;31m\1\e[0m/g" 

Мне нужно было бы отменить эти / заставить работать, т. Е.

 MATCH=\/dev\/ printf "aaa\n/dev/aaa\nccc\n" | perl -pe "s/($MATCH)/\e[1;31m\1\e[0m/g" 

Но я не знаю, что будет содержать MATCH . Это может быть что угодно, + или ( .) Есть ли способ сказать perl относиться к буквам буквально, а не как к выражению?

ОБНОВИТЬ:

Используя решение, предложенное Joseph R. следующую ошибку:

 MATCH=/dev/ printf "aaa\n/dev/aaa\nccc\n" | perl -pe "s/\Q($MATCH)\E/\e[1;31m\1\e[0m/g" Backslash found where operator expected at -e line 1, near ")\" (Missing operator before \?) Having no space between pattern and following word is deprecated at -e line 1. syntax error at -e line 1, near "s/\Q(/dev/)" Search pattern not terminated at -e line 1. 

UPDATE2:

теперь я не получаю никаких ошибок, но похоже, что нет совпадения (нет раскраски):

 # MATCH=/dev/ ; printf "aaa\n/dev/aaa\nccc\n" | perl -pe 's/(\Q$ENV{MATCH}\E)/\e[1;31m\1\e[0m/g' aaa /dev/aaa ccc 

Да, вы можете использовать оператор quotemeta Perl с одинарными кавычками:

 export MATCH=... ... | perl -pe 's/(\Q$ENV{MATCH}\E)/... 

Все, что находится между \Q и \E (или до конца регулярного выражения, если нет \E поставляется) рассматривается как -то без специального значения, прикрепленного к метасимволам.

Эквивалентное:

 export MATCH=... ... | perl -pe '$sane=quotemeta $ENV{MATCH};s/($sane)/... 

Обновить

Вот как это можно сделать без export :

 MATCH=/dev/ printf "aaa\n/dev/aaa\nccc\n" \ | perl -pe "\$sane=quotemeta q{$MATCH};s/(\$sane)/\e[1;31m\$1\e[0m/g" 

Обратите внимание, что ваш код ошибся. Вы не можете использовать backreference ( \1 ) в шаблоне замены s/// , вместо этого вам нужно использовать переменную match ( $1 ), которую я использовал как \$1 здесь, чтобы избежать интерполяции оболочки $1 потому что мягких котировок.

В общем, если вы делаете много раскраски с Perl, я бы предложил использовать модуль для обработки терминальных особенностей для вас. Обратите внимание на Термин :: ANSIColor .