Как синтаксически выделить вывод bash (некоторая справочная информация)?
Очень часто я получаю некоторую справочную информацию с --help
флаг команды, которая дает вывод на терминал, как:
$ vmtkimagereader --help
Creating vmtkImageReader instance.
Automatic piping vmtkimagereader
Parsing options vmtkimagereader
vmtkimagereader : read an image and stores it in a vtkImageData object
Input arguments:
-id Id (str,1); default=0: script id
-handle Self (self,1): handle to self
-disabled Disabled (bool,1); default=0: disable execution and
piping
Я хочу, чтобы синтаксис выделил выходные данные, как верхняя половина ссылки (извините, что я могу опубликовать только 1 ссылку). Я попытался выделить и пигментировать. Однако в highlight необходимо указать синтаксис, и pygmentize отобразит вывод как неправильный стиль (в нижней половине ссылки).
Я хотел бы знать, если есть метод, чтобы выделить синтаксис, как это. Нужно ли указывать стиль для пигментирования? Или я должен обратиться к другому решению?
Спасибо!
2 ответа
ANSI escape-строки
Используя escape-последовательности ANSI для достижения желаемого, вы можете создать строку формата (представленную \e[
и добавлен m
) где 38;5;{0..255}
это 256-цвет текста (0..255
диапазон доступных цветовых кодов), и 48;5;{0..255}
это 256-цвет фона. Например,
echo -e "\e[38;5;0;48;5;255mText\e[0m"
напечатает черный текст (цветной код 0
) с белым фоном (цветовой код 255
). Обратите внимание, с echo
команда требует расширенного режима (переключается -e
флаг) для интерпретации управляющей строки ANSI.
Обратите внимание на трейлинг \e[0m
сбросить окраску, иначе весь текст печатается после этой команды с echo
сохранит формат. \e[0m
сбрасывает его.
Обратите внимание на интересный вариант использования, который также вызывает ошибку. Размещение восклицательного знака перед финалом \e[0m
вызывает этот вывод:
nick@nick-lt:~$ echo -e "\e[38;5;0;48;5;255mText!\e[0m"
bash: !\e[0m: event not found
Это потому что !
является частью расширения строки для Bash. Подробнее об этом вопросе смотрите здесь. Чтобы сделать эту работу, как ожидалось, нам нужно сделать:
echo -e "\e[38;5;0;48;5;255mText"'!'"\e[0m"
поскольку одинарные кавычки не расширяются.
Как напечатать каждый доступный цвет, используя escape-последовательности ANSI.
Сохраните их в файле с именем color-functions.sh
:
function color_list_text() {
# First paramter can be an optional background color
local BGCOLOR="$1"
COLOR=
# Loop through the number range 0 to 255
for COLOR in {0..255}; do
local BGCOLORFORM=""
# If our first parameter has a value, then create a background
# format in ANSI escape sequence, assign to $BGCOLORFORM
[[ -z "$BGCOLOR" ]] && BGCOLORFORM="48;5;${BGCOLOR};"
# Create the whole ANSI escape sequence, assign to $TEXTFORM
local TEXTFORM="${BGCOLORFORM}38;5;${COLOR}m"
echo -en "\e[${TEXTFORM} ${COLOR}\t\e[0m"
[[ $(( (COLOR + 1) % 16 )) -eq 0 ]] && echo
done
return 0
}
function color_list_text_backgrounds() {
local TEXTCOLOR="$1"
local COLOR
for COLOR in {0..255}; do
local TEXTCOLORFORM=""
[[ -z "$TEXTCOLOR" ]] && TEXTCOLORFORM="38;5;${TEXTCOLOR};"
local TEXTFORM="${TEXTCOLORFORM}48;5;${COLOR}m"
echo -en "\e[${TEXTFORM} ${COLOR}\t\e[0m"
[[ $(( (COLOR + 1) % 16 )) -eq 0 ]] && echo
done
return 0
}
Затем в другом файле вызовите функции после того, как вы source
сделал их:
source color-functions.sh
# Loops through and prints all ANSI escape sequence's available text colors
color_list_text
# Loops through and prints all ANSI escape sequence's available text backgrounds
color_list_backgrounds
Вот функция, которая выполняет оба действия... Но я думаю, что это излишне, потому что вывод слишком велик (будет выведено 256 * 256 = 2^16 комбинаций):
function color_list_text_and_backgrounds() {
local BG
for BG in {0..255}; do
local TEXT
for TEXT in {0..255}; do
echo -en "\e[38;5;${TEXT};48;5;${BG}m ${TEXT}\t\e[0m"
if [[ $(( (TEXT + 1) % 8 )) -eq 0 ]]; then
if [[ $(( ((TEXT + 1) / 8) )) -eq 16 ]]; then
local INVBG=$(( (BG + 128) % 256 ))
echo -en "\e[38;5;${INVBG};48;5;${BG}m ${BG}\t\e[0m"
else
echo -en "\e[48;5;${BG}m\t\e[0m"
fi
echo
fi
done
done
return 0
}
Ваш вариант использования
Чтобы раскрасить определенные вещи в определенные цвета, мы можем использовать egrep -i
(-i
флаг нечувствителен к регистру) и GREP_COLOR
переменная:
echo "Some string to color" | \
GREP_COLOR='38;5;200' egrep -i --color=always 'some' | \
GREP_COLOR='38;5;100' egrep -i --color=always 'string|color'
Или мы могли бы быть очень умными и функционировать так:
color_text_match() {
MATCHSTRING="$1"
COLOR="$2"
[[ -z "$MATCHSTRING" ]] && echo "color_text_match: No color specifies."
[[ -z "$COLOR" ]] && COLOR="214" # Default orange
GREP_COLOR="38;5;$COLOR" egrep -i --color=always "$MATCHSTRING"
}
Затем:
echo "Some string to color" | \
color_text_match "Some" | \
color_text_match "string" | \
color_text_match "to" "226"
Спасибо, @NickBull. Ваше введение в ANSI escape - довольно хороший урок для новичков, таких как я:-) Я перепробовал весь ваш код и сделал мой color_help.sh
сделать вывод:
function color_help() {
COLOR_NUM="5"
COLOR_CAP_WORD="4"
COLOR_KEY_WORD="2"
GREP_COLOR="38;5;$COLOR_NUM" egrep -E --color=always "\b[0-9]+(\.[0-9]+)*\b|$" | \
GREP_COLOR="38;5;$COLOR_CAP_WORD" egrep -E --color=always "\b([A-Z][a-z]+)+\b|$" | \
GREP_COLOR="38;5;$COLOR_KEY_WORD" egrep -E --color=always "\b(and|bool|default|float|for|from|int|self|str)\b|$"
}