从字符串

时间:2019-03-03 00:43:55

标签: bash logging sed colors ansi

此处的应用程序正在“清理”包含在日志文件中的字符串。为了论证,我们假设1)在运行时为字符串着色是正确的;和2)我需要在屏幕上放置前导和尾随空格,但是从日志中删除了多余的空白。

此处的特定应用程序已准备好进入日志文件。并非所有的行都会被着色,也不是所有的行都具有前导/尾随空格。

鉴于此,我想

  1. 删除所有设置颜色 重设的代码。原因很快就会明白
  2. 删除开头和结尾的空格

在任何地方搜索如何去除bash中的颜色代码时,可以找到many different ways来完成它。然而到目前为止,我发现没有人似乎能解决尾随的复位。 $(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 :(得分:0)

这对我有用:

$ 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 does not support非贪婪的正则表达式可以消除第二个正则表达式。

编辑: 这应该适用于您输入的内容:

$ 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

与bash替换相比,我发现sed的隐喻性(或正则表达式的隐秘性)要低得多。但这就是我:)

答案 1 :(得分:0)

  

我愿意看到自己的方式的错误,……

主要错误是sed命令仅删除了 Esc […”控制序列,而没有删除 Esc B 序列,它也是sgr0的一部分。如果将其更改为

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

第二个错误是sed -n -e 'l'命令在行尾添加了文字$,因此以前的尾随空格不再尾随,因此不会被删除。