Убрать из строки начальные и конечные коды ANSI / tput - PullRequest
0 голосов
/ 03 марта 2019

Приложение здесь - «санация» строк для включения в файл журнала.В качестве аргумента давайте предположим, что 1) правильное окрашивание строки во время выполнения;и 2) Мне нужны начальные и конечные пробелы на экране, но лишние пробелы удалены из журнала.

Конкретное приложение здесь включается в файл журнала.Не все строки будут раскрашены, и не все строки будут иметь начальные / конечные пробелы.

Учитывая это, я хочу

  1. Удалить все коды и установить цвет и сброс.Причина этого будет очевидна через мгновение
  2. Удалите начальные и конечные пробелы

Когда вы ищете (где угодно), как разделять цветовые коды в bash, вы можете найти много разных способов сделать это.Однако то, что я обнаружил до сих пор, так это то, что никто не обращает внимания на конечный сброс;$ (tput sgr0).В примерах, которые я видел, это несущественно, однако мое дополнительное требование убрать начальные / конечные пробелы усложняет / делает это требованием.

Вот мой пример сценария, который демонстрирует проблему:

#!/bin/bash

# Create a string with color, leading spaces, trailing spaces, and a reset
REPLY="$(tput setaf 2)       This is green        $(tput sgr0)"
echo "Colored output:  $REPLY"
# Remove initial color code
REPLY="$(echo "$REPLY" | sed 's,\x1B\[[0-9;]*[a-zA-Z],,g')"
echo "De-colorized output:  $REPLY"
# Remove leading and trailing spaces if present
REPLY="$(printf "%s" "${REPLY#"${REPLY%%[![:space:]]*}"}" | sed -n -e 'l')"
echo "Leading spaces removed:  $REPLY"
REPLY="$(printf "%s" "${REPLY%"${REPLY##*[![:space:]]}"}" | sed -n -e 'l')"
echo "Trailing spaces removed:  $REPLY"

Вывод (не могу понять, как здесь закрасить текст, предположим, что первая строка зеленая, а последующие строки нет):

screen cap

Я желаю увидеть ошибку моих способов, но после примерно трех часов, пробуя разные вещи, я почти уверен, что мое google-fu меня подводит.

Спасибо за любую помощь.

Ответы [ 2 ]

0 голосов
/ 04 марта 2019

Я желаю увидеть ошибку моих путей,…

Основная ошибка в том, что команда sed удаляет только Esc [… управляющие последовательности, но не последовательность Esc ( B , которая также является частью sgr0. Она работает, если вы измените ее на

… | sed 's,\x1B[[(][0-9;]*[a-zA-Z],,g'

Вторичной ошибкой является то, что команда sed -n -e 'l' добавляет буквальный знак $ в конце строки, поэтому прежние конечные пробелы больше не завершаются и, следовательно, не удаляются.

0 голосов
/ 03 марта 2019

Это работает для меня:

$ REPLY="$(tput setaf 2)       This is green        $(tput sgr0)"
$ echo -n $REPLY | od -vAn -tcx1
 033   [   3   2   m                               T   h   i   s
  1b  5b  33  32  6d  20  20  20  20  20  20  20  54  68  69  73
       i   s       g   r   e   e   n                            
  20  69  73  20  67  72  65  65  6e  20  20  20  20  20  20  20
     033   [   m 017
  20  1b  5b  6d  0f
$ REPLY=$(echo $REPLY | sed -r 's,\x1B[\[\(][0-9;]*[a-zA-Z]\s*(.*)\x1B[\[\(].*,\1,g' | sed 's/\s*$//')
$ echo -n $REPLY | od -vAn -tcx1
   T   h   i   s       i   s       g   r   e   e   n
  54  68  69  73  20  69  73  20  67  72  65  65  6e

Видимо sed не поддерживает не жадное регулярное выражение, которое бы исключило второе регулярное выражение.

EDIT: Это должно работать для ввода, который у вас есть:

$ REPLY="$(tput setaf 2)       This is green        "$'\x1B'"(B$(tput sgr0)"
$ echo -n $REPLY | od -vAn -tcx1
 033   [   3   2   m                               T   h   i   s
  1b  5b  33  32  6d  20  20  20  20  20  20  20  54  68  69  73
       i   s       g   r   e   e   n                            
  20  69  73  20  67  72  65  65  6e  20  20  20  20  20  20  20
     033   (   B 033   [   m 017
  20  1b  28  42  1b  5b  6d  0f
$ REPLY=$(echo "$REPLY" | sed -r -e 's,\x1B[\[\(][0-9;]*[a-zA-Z]\s*([^\x1B]+)\s+\x1B.*,\1,g' -e 's,\s*$,,')
$ echo -n $REPLY | od -vAn -tcx1
   T   h   i   s       i   s       g   r   e   e   n
  54  68  69  73  20  69  73  20  67  72  65  65  6e

Я считаю, что sed гораздо менее загадочен (или менее загадочен, чем регулярные выражения) по сравнению с подстановками bash.Но это только я:)

...