2015-12-21 2 views
4

Я использую диф форматировать строку, которая включает в себя tput цветовых переменных, и я не в состоянии иметь эти переменные оценено без использования «зла» eval команды.Оценка цвета отформатированного вывода команды

Команда, которая создает строку:

output1="$(diff --changed-group-format="\${RED}%=\${CLS}" <(echo -e "${nstr1}") <(echo -e "${nstr2}")|tr -d '\n')" 

и выводит:

[String n${RED}â${CLS}m${RED}è™${CLS}] 

Я смотрел и искал другие ответы, но ничего не работает, кроме:

eval echo "${output1}" 

Из того, что я прочитал, мои 3 варианта: eval (bad), косвенное расширение (лучше), и массивы (best). Каждая попытка косвенного провала не удалась. Я хотел бы использовать параметр массива, но я просто не вижу, как он будет применяться здесь. Я что-то упускаю?

Я не думаю, что это релевантно, но переменные и строение строк, отправленных на diff, находятся в другом вопросе here.

ответ

1

Вы можете использовать расширение параметров Bash, если вы готовы сделать с конечным, известный в своем заранее набор цветовых кодов:

#!/usr/bin/env bash 

# Define the variables containing ANSI color sequences. 
RED="$(tput setaf 1)" 
CYA="$(tput setaf 6)" 
CLS="$(tput sgr0)" 

# Sample input string 
str='[String n${RED}â${CLS}m${CYA}è™${CLS}]' 

# Replace the placeholders with their corresponding variable values. 
str=${str//'${RED}'/${RED}} 
str=${str//'${CYA}'/${CYA}} 
str=${str//'${CLS}'/${CLS}} 

# Output the result. 
echo "$str" 

Этот подход имеет преимущество в том, что аргумент используемый в расширении параметров Bash сами подвержены растяжению, если в одинарных кавычках:

  • ${<varName>//<search>/<replace>} заменяет все экземпляры <search> с <replace> в значении переменной <varName>.
  • '${RED}', например, из-за наличия одинарная котировка - принимается за буквально срок поиска.
  • ${RED}, например - из-за того неупомянута - это расширен перед использованием в качестве замены термина, следовательно, эффективно заменяя буквального${RED} с значения переменной${RED}.

Облаченный в функции:

printColored() { 
    local str=$1 
    local RED="$(tput setaf 1)" CYA="$(tput setaf 6)" CLS="$(tput sgr0)" 
    str=${str//'${RED}'/${RED}} 
    str=${str//'${CYA}'/${CYA}} 
    str=${str//'${CLS}'/${CLS}} 
    printf '%s\n' "$str" 
} 

printColored '[String n${RED}â${CLS}m${CYA}è™${CLS}]' 

Кстати, я бы переименовать ${CLS} в ${RST} (для «сброса») или что-то подобное, так как термин «ЦБС» предлагает очищая весь экран.

+0

Я не понимаю, почему это работает, но это так! Разве полученная строка не идентична? Если это вопрос прохождения движений, я мог бы использовать более короткий заполнитель правильно? Кроме того, у меня уже есть эти переменные во всем мире, поэтому я не должен был объявлять их локальными здесь правильно? (RED, CYA и т. Д.) Наконец, отличный совет по cls, который получил прямо у меня. – akovia

+0

@akovia: Посмотрите, объясняет ли это обновление. Да, вы могли бы использовать более короткие заполнители.Если вы используете глобальные переменные, вам не нужно объявлять их внутри функции, но для лучшей инкапсуляции вы можете это сделать. – mklement0

+1

Спасибо за расширение объяснения. Это работает красиво! – akovia

Смежные вопросы