Функции, содержащие переменные bash, вставленные в строки perl через переменные, переданные через начало функции - PullRequest
2 голосов
/ 29 февраля 2020
greenh='\e[2;30;42m$&\e[0m/g'
yellowh='\e[2;30;43m$&\e[0m/g'
aquah='\e[2;30;46m$&\e[0m/g'

function recolor() { 
perl -pe "s/$1/$2"
}

я использую это, чтобы перекрасить текст

ПРИМЕР:

cat file.txt | recolor WHATEVERWORD $greenh

Есть ли способ, которым я могу включить $ в функцию, чтобы я мог использовать его как

cat file.txt | recolor WHATEVERWORD greenh

Я пытался

function recolor() { 
perl -pe "s/$1/$$2"
}

function recolor() { 
perl -pe "s/$1/\$$2"
}

Они оба просто полностью нарушают функцию ...

Ответы [ 2 ]

5 голосов
/ 29 февраля 2020

Это действительно неправильный подход; Вы собираете кучу хаков, которые «просачиваются» в разные слои. (Например, рассмотрим recolor 'x//g;#' greenh, который предназначен для принятия вхождений x//g;# и окрашивания их в зеленый цвет, но который фактически принимает вхождения x и удаляет их; или recolor foo blueh, который предназначен для вхождения foo и закрасьте их синим, но на самом деле это не работает, потому что ваша функция тайно зависит от устанавливаемой глобальной переменной, а пользователь не определил $blueh.)

Я думаю, вам лучше просто определяя отдельные функции:

greenh()  { pat="$1" perl -pe 's/$ENV{pat}/\e[2;30;42m$&\e[0m/g' ; }
yellowh() { pat="$1" perl -pe 's/$ENV{pat}/\e[2;30;43m$&\e[0m/g' ; }
aquah()   { pat="$1" perl -pe 's/$ENV{pat}/\e[2;30;46m$&\e[0m/g' ; }

Если вы действительно хотите одну recolor функцию, то вам лучше определить цвета внутри нее:

recolor() {
  perl -e '
    my $prefix =
      {
        "greenh"  => "\e[2;30;42m",
        "yellowh" => "\e[2;30;43m",
        "aquah"   => "\e[2;30;46m",
      }->{$color};
    die "Unrecognized color $color" unless $prefix;
    while (<>) {
      s/$pat/$prefix$&\e[0m/g;
      print;
    }
  ' -s -- -pat="$1" -color="$2"
}

(для полноты ' ради, однако, я должен упомянуть, что Bash поддерживает переменную косвенность, если $2 равен greenh, то ${!2} равен $greenh, но эту функцию обычно лучше избегать, и ваш пример именно поэтому .)

2 голосов
/ 29 февраля 2020

Как вам уже сказали (когда ваш предыдущий экземпляр этого вопроса был закрыт как дубликат) - реализовать замену, которую вы ищете в bash, независимо от того, что лучше -practice Perl решение будет, вы бы использовали ${!varname} для поиска переменной , имя которой хранится в varname. В этом случае вы хотите найти переменную, имя которой хранится в $2, поэтому вы должны использовать ${!2}:

aquah='\e[2;30;46m$&\e[0m/g'

recolor() { perl -pe "s/$1/${!2}"; }

echo "hello" | recolor lo aquah

..., которая успешно окрашивает lo в aquah. Подробнее см. BashFAQ # 6 .


Тем не менее, использование конкатенации строк для динамического генерирования кода никогда хорошая идея. Не делай этого. Гораздо безопаснее передавать ваши значения в perl в качестве переменных среды или отдельных элементов argv, а не подставлять их в код.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...