如何在保留显示格式的同时将转义序列转换为文本?

如何在保留显示格式的同时将转义序列转换为文本?

我有一个包含(ANSI?)转义序列的文本文件:

原始文件

当我cat输入文件时,我得到格式化输出:

格式化输出

如何将文本文件的输出保存/通过管道传输到新文件,以便删除控制代码但保留格式?

换句话说,我想将文件的内容转换/导出到新文件,同时保留预期的显示格式(例如,就像使用时得到的那样less -r <file>)。

我需要一种自动化的方法来执行此操作,以便可以记录输出并将其作为电子邮件通知发送。

这是上面屏幕截图中文件的 Base64 输出(用于base64 -d解码它):

G1tIG1syShtbMTsxSA0KG1s0OzRIICAgICAgICAgICAgICAgICAgICAgICAgICBDT05GSURFTlRJ
QUwgSU5GT1JNQVRJT04bW0sbWzU7NEgbW0sbWzY7NEgbW0sbWzc7NEhUaGlzIHdvcmsgY29udGFp
bnMgdmFsdWFibGUsIGNvbmZpZGVudGlhbCwgYW5kIHByb3ByaWV0YXJ5IGluZm9ybWF0aW9uLhtb
SxtbODs0SERpc2Nsb3N1cmUsIHVzZSwgb3IgcmVwcm9kdWN0aW9uIGlzIGdvdmVybmVkIGJ5IHlv
dXIgTGljZW5zZSBBZ3JlZW1lbnQuG1tLG1sxMDs0SBtbSxtbMTE7NEhUaGlzIHVucHVibGlzaGVk
IHdvcmsgaXMgcHJvdGVjdGVkIGJ5IHRoZSBsYXdzIG9mIHRoZSBVbml0ZWQgU3RhdGVzIGFuZBtb
SxtbMTI7NEhvdGhlciBDb3VudHJpZXMuICBUaGUgd29yayB3YXMgY3JlYXRlZCBpbiAxOTg4IGFu
ZCByZXZpc2VkIGluIDE5OTQuICAbW0sbWzEzOzRISWYgcHVibGljYXRpb24gb2NjdXJzLCB0aGUg
Zm9sbG93aW5nIG5vdGljZSBzaGFsbCBhcHBseTobW0sbWzE0OzRIG1tLG1sxNTs0SBtbSxtbMTY7
NEggICBDb3B5cmlnaHQgMTk4OCwxOTk0LiBBbGwgcmlnaHRzIHJlc2VydmVkLhtbSxtbMTc7NEgb
W0sbWzE4OzRIG1tLG1sxOTs0SFRoaXMgQ29weXJpZ2h0IG5vdGljZSBhbmQgb3RoZXIgY29weXJp
Z2h0IG5vdGljZXMgaW5jbHVkZWQgaW4gdGhlIG1hY2hpbmUbW0sbWzIwOzRIcmVhZGFibGUgY29w
aWVzIG11c3QgYmUgcmVwcm9kdWNlZCBvbiBhbGwgYXV0aG9yaXplZCBjb3BpZXMuG1tLG1syMTs0
SBtbSxtbMjI7NEhUaGlzIGlzIGEgcmVnaXN0ZXJlZCB0cmFkZW1hcmsuG1tLDQo=

答案1

最好的办法是让终端模拟器解释这些序列,并告诉它转储结果中的文本部分。

screen是您可以在脚本中轻松与之交互的终端模拟器之一。你可以这样做:

INPUT=file.txt OUTPUT=output.txt screen -Dmc /dev/null sh -c '
  screen -X scrollback 100000
  cat < "$INPUT"
  screen -X hardcopy -h "$OUTPUT"'

这将使用空onfig 文件 ( ) 启动一个新的 ( -m)蚀刻屏幕会话。在那里,我们在屏幕窗口中运行该内联脚本,增加回滚大小(尽管这里的输出适合一个屏幕),将输入文件转储到屏幕窗口中,然后调用转储屏幕内容,包括回滚到输出文件中。Dc/dev/nullshhardcopy -h

答案2

该文件包含许多转义序列(字符序列^[是转义字符):

  • ^[[2J,清除屏幕。

  • ^[[H,将光标移动到屏幕顶部。

  • ^[[x;yH,将光标移至位置(x,y)

    这意味着该文件基本上使用文本在屏幕上的位置的绝对定位。

  • ^[[K清除到行尾。

该文件还包含一些我们可能想要删除的回车符。

我们可以选择删除其中的大部分,但(x,y)为了简单起见,用单个换行符替换“移动到”序列。幸运的是,每次这样的定位只是将光标向下移动一行,并将其缩进四个空格(不存在“不按顺序”的文本行)。

sed -e $'s/\e\\[2J//g' \
    -e $'s/\e\\[H//g' \
    -e $'s/\e\\[[[:digit:]]*;[[:digit:]]*H/@    /g' -e 'y/@/\n/' \
    -e $'s/\e\\[K//g' \
    -e $'s/\r//g' file

这里的替换是使用 shell 中的 C 字符串(由eg和$'...'支持)来对转义字符进行编码。bashzsh

每个^[[x;yH序列都以两步方式替换为换行符和四个缩进空格;首先将它们替换为@    (@是数据中不存在的任何字符),然后@ 使用 将每个字符替换为换行符y///。这是由于s///无法插入换行符(尽管 GNUsed可以)。

我们还可以选择使用cat -v数据运行的输出。这使得一些控制字符以明确的方式可见。

$ cat -v file
^[[H^[[2J^[[1;1H^M
^[[4;4H                          CONFIDENTIAL INFORMATION^[[K^[[5;4H^[[K^[[6;4H^[[K^[[7;4HThis work contains valuable, confidential, and proprietary information.^[[K^[[8;4HDisclosure, use, or reproduction is governed by your License Agreement.^[[K^[[10;4H^[[K^[[11;4HThis unpublished work is protected by the laws of the United States and^[[K^[[12;4Hother Countries.  The work was created in 1988 and revised in 1994.  ^[[K^[[13;4HIf publication occurs, the following notice shall apply:^[[K^[[14;4H^[[K^[[15;4H^[[K^[[16;4H   Copyright 1988,1994. All rights reserved.^[[K^[[17;4H^[[K^[[18;4H^[[K^[[19;4HThis Copyright notice and other copyright notices included in the machine^[[K^[[20;4Hreadable copies must be reproduced on all authorized copies.^[[K^[[21;4H^[[K^[[22;4HThis is a registered trademark.^[[K^M

在这里,我们可以使用以下sed命令:

cat -v file |
sed -e 's/\^\[\[2J//g' \
    -e 's/\^\[\[H//g' \
    -e 's/\^\[\[[[:digit:]]*;[[:digit:]]*H/@    /g' -e 'y/@/\n/' \
    -e 's/\^\[\[K//g' \
    -e 's/\^M//g'

请注意,-v选项cat不是标准的,但支持它的实现的输出cat似乎是一致的。

在某些系统上,该vis实用程序可以用来代替cat -v,但它会生成控制字符的其他可见表示。

答案3

使用带有删除选项的截断命令的简单方法。 \033 代表转义字符。

$cat your_filename|tr -d \033 > save_filename

使用以下命令删除所有控制字符

$cat your_filename|tr -d [:cntrl:] > save_filename



希望有帮助

相关内容