Как я могу сказать echo/printf в Bash глотать управляющие коды, на основе условия?

С FreeBSD / Mac OS X find, stat и awk (не точно удобная острота, хотя):

find -x . -type f -maxdepth 1 -exec sh -c 'stat -f '%z' "${@}"' _ '{}' + | 
LC_ALL=C awk -v pwd="${PWD}" '
   BEGIN{ sum=0; count=0; }
   { sum+=$1; ++count; }
   END{ 
        if (count == 0) exit;
        printf ("number of files: %d\n", count); 
        printf ("average file size in B: %.5f\n", sum/count); 
        printf ("average file size in KB: %.5f\n", (sum/count) / 1024); 
        printf ("average file size in MB: %.5f\n", (sum/count) / (1024*1024)); 
        printf ("directory: %s\n", pwd); 
   }
'
2
13.04.2017, 15:36
3 ответа

Не точно глотая, но можно удалить их с расширением параметра:

str='Hello \e[31mc\e[32mo\e[33ml\e[34mo\e[35mr\e[m world'

# colorful output
echo -e "$str"

# colorless output    
echo -e "${str//\\e\[+([0-9;])m}"

Вышеупомянутое в bash требует extglob опция оболочки, которая будет включена. (shopt -s extglob)

Чтобы помочь использовать, определите функцию:

function ecco() { [ -t 1 ] && echo -e "$1" || echo -e "${1//\\e\[+([0-9;])m}"; }

Затем Вы просто называете его:

ecco 'Hello \e[31mc\e[32mo\e[33ml\e[34mo\e[35mr\e[m world'

Чтобы проверить, что это работает, просто перенаправьте его вывод, и цвета исчезнут:

ecco 'Hello \e[31mc\e[32mo\e[33ml\e[34mo\e[35mr\e[m world' | cat
2
27.01.2020, 21:54
  • 1
    Это - очень умная мысль.Спасибо. Принятие. –  0xC0000022L 19.11.2013, 22:01
  • 2
    Вы пропускаете часть, где Вы определяете, сделать ли фильтрацию. –  Gilles 'SO- stop being evil' 20.11.2013, 02:15

Проверьте, печатаете ли Вы к терминалу. Это что программы, такие как GNU ls и GNU grep сделайте, когда Вы скажете им --color=auto.

Даже если Вы печатаете к терминалу в теории, это не могло бы понять изменяющие цвет escape-последовательности. На практике все общее и большинство not-so-common терминалов понимают эти последовательности: все эмуляторы терминала X11 я когда-либо видел, экран, tmux, консоль Linux, *консоли BSD, PuTTY, rxvt, Console2, ConEmu, …

normal=
green=
…
if [ -t 1 ]; then
  normal=$'\e[0m'
  green=$'\e32m'
  …
 fi
 …
 echo "foobar ${green}OK${normal}"

Тест [ -t 1 ] для стандартного вывода и [ -t 2 ] для стандартной погрешности.

В оболочках, которые не поддерживают $'…' расширение, можно генерировать символ ESC портативно с esc=$(echo _ | tr _ '\033')

3
27.01.2020, 21:54

необходимо ли просто проверить в сценарии, если он выполняется в интерактивном режиме или нет?

http://www.gnu.org/software/bash/manual/html_node/Is-this-Shell-Interactive_003f.html

Кавычки:

6.3.2 Действительно ли этот Shell является Интерактивным?

Для определения в рамках сценария запуска, работает ли Bash в интерактивном режиме протестируйте значение ‘-’ специальный параметр. Это содержит меня, когда оболочка является интерактивной. Например:

case "$-" in
  *i*)   echo This shell is interactive ;;
   *)    echo This shell is not interactive ;;
esac

С другой стороны, сценарии запуска могут исследовать переменный PS1; это сброшено в неинтерактивных оболочках и установлено в интерактивных оболочках. Таким образом:

if [ -z "$PS1" ]; then
   echo This shell is not interactive
else
   echo This shell is interactive
fi

и определите ряд переменных к "_escape_codes _", если это будет интерактивным и к "" в противном случае, и используйте те переменные для colorize вывод в сценарии (в интерактивной среде, у них будут управляющие коды, то в неинтерактивном они ничего не добавят к тексту).

исключая:

case "$-" in
  *i*)    _bold_="$(printf '\033[1m')"
          _norm_="$(printf '\033[0m')"
          ;;
  *)      _bold_=""
          _norm_=""
          ;;
esac
echo "this ${_bold_}text${_norm_} is important"
1
27.01.2020, 21:54
  • 1
    , что я знаю двойные кавычки вокруг своего "$ (...)", не нужно здесь, но я предпочитаю входить в привычку при определении переменных... и этого colorizes "лучше" (ymmv) в некоторых редакторах. –  Olivier Dulac 19.11.2013, 21:52
  • 2
    Является ли оболочка интерактивной, не проблема здесь. Скрипт не будет запущен интерактивной оболочкой, что имеет значение, является ли stdout (или stderr в зависимости от обстоятельств) терминалом. –  Gilles 'SO- stop being evil' 20.11.2013, 02:14
  • 3
    @Gilles: хорошие взгляды. Вы правы! –  Olivier Dulac 20.11.2013, 11:16

Теги

Похожие вопросы