如何使用 linux shell 脚本删除文件中的 ^[ 和所有转义序列



我们要删除^[和所有转义序列。

sed 不起作用,并给我们此错误:

$ sed 's/^[//g' oldfile > newfile; mv newfile oldfile;
sed: -e expression #1, char 7: unterminated `s' command
$ sed -i '' -e 's/^[//g' somefile
sed: -e expression #1, char 7: unterminated `s' command

你在寻找安西过滤器吗?


您可以做的两件事:输入文字转义(在 bash 中:(

使用键盘输入:

sed 's/Ctrl-vEsc//g'

或者

sed 's/Ctrl-vCtrl-[//g'

或者,您可以使用字符转义:

sed 's/x1b//g'

或对于所有控制字符:

sed 's/[x01-x1Fx7F]//g' # NOTE: zaps TAB character too!

commandlinefu 给出了去除 ANSI 颜色和移动命令的正确答案:

sed "s,x1B[[0-9;]*[a-zA-Z],,g"

出于我的目的,我管理了以下内容,但这不包括所有可能的 ANSI 转义:

sed -r s/x1b[[0-9;]*m?//g

这将删除m命令,但对于所有转义(如@lethalman注释所示(,请使用:

sed -r s/x1b[[^@-~]*[@-~]//g

另请参阅"https://stackoverflow.com/questions/7857352/python-regex-to-match-vt100-escape-sequences"。

还有一个常见转义序列表。

ansi2txt命令(kbtin包的一部分(似乎在Ubuntu上完美地完成了这项工作。

我没有足够的声誉来为 Luke H 给出的答案添加注释,但我确实想分享我一直用来消除所有 ASCII 转义序列的正则表达式。

sed -r 's~x01?(x1B(B)?x1B[([0-9;]*)?[JKmsu]x02?~~g'

在寻找一种从手册页中删除额外格式的方法时,我偶然发现了这篇文章。 AnsiFilter 做到了,但它远非预期的结果(例如,所有以前粗体字符都被复制,如 SSYYNNOOPPSSIISS (。

对于该任务,正确的命令是 col -bx ,例如:

groff -man -Tascii fopen.3 | col -bx > fopen.3.txt

(来源(

为什么这样做:(回应@AttRigh的评论(

groff生成粗体字符,就像在打字机上一样:打印一个字母,使用退格键将一个字符移回(您无法擦除打字机上的文本(,再次打印相同的字母以使字符更明显。因此,简单地省略退格会产生"SSYYNNOOPPSSIISS"。 col -b通过正确解释退格键来解决此问题,请引用手册中的以下内容:

-b 不输出任何退格符,只打印写入每个列位置的最后一个字符。

您可以使用以下命令删除所有不可打印的字符:

sed 's/[^[:print:]]//g'

我为此构建了vtclean。它按顺序使用这些正则表达式去除转义序列(在正则表达式.txt中解释(:

// handles long-form RGB codes
^33](d+);([^33]+)33\
// excludes non-movement/color codes
^33([[^a-zA-Z0-9@?]+|[()]).
// parses movement and color codes
^33([[]]([d?]+)?(;[d?]+)*)?(.)`)

它还执行基本的行编辑模拟,因此会解析退格键和其他移动字符(如左箭头键(。

只是一个注释;假设您有一个这样的文件(此类行尾由git远程报告生成(:

echo -e "remote: * 27625a8 (HEAD, master) 1st git commitx1b[K
remote: x1b[K
remote: x1b[K
remote: x1b[K
remote: x1b[K
remote: x1b[K
remote: Current branch master is up to date.x1b[K" > chartest.txt

在二进制中,这看起来像这样:

$ cat chartest.txt | hexdump -C
00000000  72 65 6d 6f 74 65 3a 20  2a 20 32 37 36 32 35 61  |remote: * 27625a|
00000010  38 20 28 48 45 41 44 2c  20 6d 61 73 74 65 72 29  |8 (HEAD, master)|
00000020  20 31 73 74 20 67 69 74  20 63 6f 6d 6d 69 74 1b  | 1st git commit.|
00000030  5b 4b 0a 72 65 6d 6f 74  65 3a 20 1b 5b 4b 0a 72  |[K.remote: .[K.r|
00000040  65 6d 6f 74 65 3a 20 1b  5b 4b 0a 72 65 6d 6f 74  |emote: .[K.remot|
00000050  65 3a 20 1b 5b 4b 0a 72  65 6d 6f 74 65 3a 20 1b  |e: .[K.remote: .|
00000060  5b 4b 0a 72 65 6d 6f 74  65 3a 20 1b 5b 4b 0a 72  |[K.remote: .[K.r|
00000070  65 6d 6f 74 65 3a 20 43  75 72 72 65 6e 74 20 62  |emote: Current b|
00000080  72 61 6e 63 68 20 6d 61  73 74 65 72 20 69 73 20  |ranch master is |
00000090  75 70 20 74 6f 20 64 61  74 65 2e 1b 5b 4b 0a     |up to date..[K.|
0000009f

可以看出,git在这里添加了行尾 (0x0a( 之前的序列0x1b 0x5b 0x4b

请注意 - 虽然您可以将0x1b与 sed 中的文字格式x1b匹配,但您不能对 0x5b 执行相同的操作,它表示左方括号[

$ cat chartest.txt | sed 's/x1bx5b//g' | hexdump -C
sed: -e expression #1, char 13: Invalid regular expression

您可能认为您可以使用额外的反斜杠来转义表示 - 最终为 \x5b ; 但是当它"通过"时 - 它与预期的任何内容都不匹配:

$ cat chartest.txt | sed 's/x1b\x5b//g' | hexdump -C
00000000  72 65 6d 6f 74 65 3a 20  2a 20 32 37 36 32 35 61  |remote: * 27625a|
00000010  38 20 28 48 45 41 44 2c  20 6d 61 73 74 65 72 29  |8 (HEAD, master)|
00000020  20 31 73 74 20 67 69 74  20 63 6f 6d 6d 69 74 1b  | 1st git commit.|
00000030  5b 4b 0a 72 65 6d 6f 74  65 3a 20 1b 5b 4b 0a 72  |[K.remote: .[K.r|
00000040  65 6d 6f 74 65 3a 20 1b  5b 4b 0a 72 65 6d 6f 74  |emote: .[K.remot|
...

因此,如果要匹配此字符,显然必须将其写为转义的左方括号,即[ - 其余值可以使用转义x表示法输入:

$ cat chartest.txt | sed 's/x1b[x4b//g' | hexdump -C
00000000  72 65 6d 6f 74 65 3a 20  2a 20 32 37 36 32 35 61  |remote: * 27625a|
00000010  38 20 28 48 45 41 44 2c  20 6d 61 73 74 65 72 29  |8 (HEAD, master)|
00000020  20 31 73 74 20 67 69 74  20 63 6f 6d 6d 69 74 0a  | 1st git commit.|
00000030  72 65 6d 6f 74 65 3a 20  0a 72 65 6d 6f 74 65 3a  |remote: .remote:|
00000040  20 0a 72 65 6d 6f 74 65  3a 20 0a 72 65 6d 6f 74  | .remote: .remot|
00000050  65 3a 20 0a 72 65 6d 6f  74 65 3a 20 0a 72 65 6d  |e: .remote: .rem|
00000060  6f 74 65 3a 20 43 75 72  72 65 6e 74 20 62 72 61  |ote: Current bra|
00000070  6e 63 68 20 6d 61 73 74  65 72 20 69 73 20 75 70  |nch master is up|
00000080  20 74 6f 20 64 61 74 65  2e 0a                    | to date..|
0000008a

基于sed的方法,没有-r启用的扩展正则表达式

sed 's/x1B[[0-9;]*[JKmsu]//g'

Tom Hale的回答留下了不需要的代码,但是一个很好的工作基础。 添加额外的过滤清除剩余的、不需要的代码:

sed -e "s,^[[[(][0-9;?]*[a-zA-Z],,g" 
    -e "s/^[[[][0-9][0-9]*[@]//" 
    -e "s/^[[=0-9]<[^>]*>//" 
    -e "s/^[[)][0-9]//" 
    -e "s/.^H//g" 
    -e "s/^M//g" 
    -e "s/^^H//" 
        file.dirty > file.clean

由于这是在非GNU版本的sed上完成的,在那里你可以看到^[^H^M,我分别使用了Ctrl-V ,Ctrl-V Ctrl-H和Ctrl-V Ctrl-M。 ^>字面上是一个克拉 (^( 和大于字符,而不是 Ctrl-<。

TERM=xterm当时正在使用。

若要删除 PCL 代码,请添加如下所示的模式:

sed -e "s/^[[&()*][a-z]*[-+]*[0-9][0-9]*[A-Z]//" 
    -e "s/^[[=9EZYz]//" 
        file.dirty > file.clean

理想情况下,如果正则表达式与理解 元字符的解释器一起使用,则第一种模式最好表示为:

      "s/^[[&()*][a-z]?[-+]?[0-9][0-9]*[A-Z]//" 
我一直

用来去除(至少一些(ANSI颜色的bash片段:

shopt -s extglob
while IFS='' read -r line; do
  echo "${line//$'x1b'[*([0-9;])[Km]/}"
done

我的回答

詹金斯用什么奇怪的 ha://URL填充我们的日志?

有效地从 Jenkins 控制台日志文件中删除所有 ANSI 转义序列(它还处理特定于 Jenkins 的 URL,这些 URL 在这里无关紧要(。

我承认并感谢Marius Gedminas和睡衣在制定最终解决方案方面的贡献。

这个简单的awk解决方案对我有用,试试这个:

str="happy $(tput setaf 1)new$(tput sgr0) year!" #colored text
echo $str | awk '{gsub("(.\[[0-9]+m|.\(..\[m)","",$0)}1' #remove ansi colors

相关内容

最新更新