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

2024-10-12 09:57:00
admin
原创
202
摘要:问题描述:我们要删除 ^[,以及所有转义序列。sed 不起作用并给出以下错误:$ sed 's/^[//g' oldfile > newfile; mv newfile oldfile; sed: -e expression #1, char 7: untermina...

问题描述:

我们要删除 ^[,以及所有转义序列。

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

解决方案 1:

您在寻找ansifilter吗?


您可以做两件事:输入文字转义符(在 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!

解决方案 2:

commandlinefu 给出了正确的答案,它剥离了 ANSI 颜色以及移动命令:

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

解决方案 3:

为了达到我的目的,我管理了以下内容,但这并不包括所有可能的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”。

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

解决方案 4:

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

解决方案 5:

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

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

解决方案 6:

在寻找从手册页中去除多余格式的方法时,我偶然发现了这篇文章。ansifilter 做到了,但远未达到预期的效果(例如,所有以前加粗的字符都被重复了,如SSYYNNOOPPSSIISS)。

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

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

(来源)

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

groff产生粗体字符,就像在打字机上一样:打印一个字母,使用退格键向后移动一个字符(您无法在打字机上擦除文本),再次打印相同的字母以使字符更明显。因此,只需省略退格键即可产生“SSYYNNOOPPSSIISS”。col -b通过正确解释退格键来解决这个问题,引自手册:

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

解决方案 7:

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

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

解决方案 8:

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

// handles long-form RGB codes
^](d+);([^]+)\

// excludes non-movement/color codes
^([[^a-zA-Z0-9@?]+|[()]).

// parses movement and color codes
^([[]]([d?]+)?(;[d?]+)*)?(.)`)

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

解决方案 9:

sed基于方法,无需扩展正则表达式-r

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

解决方案 10:

只需注意;假设您有一个这样的文件(这样的行尾由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添加了序列。0x1b 0x5b 0x4b`0x0a`

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

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

您可能认为可以使用额外的反斜杠来转义该表示`- 最终结果为[`; 但是虽然它“通过”了 - 但它并没有匹配任何预期的内容:

$ cat chartest.txt | sed 's/x1b[//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

解决方案 11:

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

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

由于这是在非 GNU 版本的 sed 上完成的,因此您会看到^[^H^M,我分别使用了 Ctrl-V <Esc>、Ctrl-V Ctrl-H 和 Ctrl-V Ctrl-M。^>实际上是插入符号 (^) 和大于号,而不是 Ctrl-<。

当时正在使用 TERM=xterm。

要删除 PCL 代码,请添加如下模式:

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

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

      &quot;s/^[[&amp;()*][a-z]?[-+]?[0-9][0-9]*[A-Z]//&quot; \n

解决方案 12:

我一直使用一个 bash 代码片段来去除(至少一些) ANSI 颜色:

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

解决方案 13:

我的回答

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

有效地从 Jenkins 控制台日志文件中删除所有 ANSI 转义序列(它还处理与此不相关的 Jenkins 特定的 URL)。

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

解决方案 14:

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

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

解决方案 15:

您可以使用astrp CLI 工具来剥离 ANSI 转义码。astrp 建立在 Alacritty 的 VTE 解析器之上,该解析器将输入传递到状态机。这种方法应该比用正则表达式替换转义码更可靠。

解决方案 16:

这些答案对我没有用。

我从 rs232 设备捕获了一个 40MB 的文本文件,其中包含 ^B 和 ^C。我删除 ^B 和 ^C 的所有努力都失败了。

要删除所有特殊字符,包括换行符n 和回车符, r 为:

cat InputFile.txt | tr -d &quot;[:cntrl:]&quot; > OutputFile.txt

tr -d &quot;[:cntrl:]&quot;从输出中删除所有控制字符。

如果要保留换行符n 和回车符 n,则一种方法可能是将 r 和 n 分别重新映射到 275 和 276,删除控制字符,然后将字符重新映射回 r 和 n,如下所示:

cat InputFile.txt | tr &#039;
&#039; &#039;½¾&#039; | tr -d &quot;[:cntrl:]&quot; | tr &quot;½¾&quot; &quot;
&quot; > OutputFile.txt

注意:如果您的文件已经包含 275 和 276 字符,则查找文件中不存在的不同字符。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1109  
  IPD(Integrated Product Development,集成产品开发)流程是一种广泛应用于高科技和制造业的产品开发方法论。它通过跨职能团队的紧密协作,将产品开发周期缩短,同时提高产品质量和市场成功率。在IPD流程中,CDCP(Concept Decision Checkpoint,概念决策检查点)是一个关...
IPD培训课程   73  
  研发IPD(集成产品开发)流程作为一种系统化的产品开发方法,已经在许多行业中得到广泛应用。它不仅能够提升产品开发的效率和质量,还能够通过优化流程和资源分配,显著提高客户满意度。客户满意度是企业长期成功的关键因素之一,而IPD流程通过其独特的结构和机制,能够确保产品从概念到市场交付的每个环节都围绕客户需求展开。本文将深入...
IPD流程   63  
  IPD(Integrated Product Development,集成产品开发)流程是一种以跨职能团队协作为核心的产品开发方法,旨在通过优化资源分配、提高沟通效率以及减少返工,从而缩短项目周期并提升产品质量。随着企业对产品上市速度的要求越来越高,IPD流程的应用价值愈发凸显。通过整合产品开发过程中的各个环节,IPD...
IPD项目管理咨询   71  
  跨部门沟通是企业运营中不可或缺的一环,尤其在复杂的产品开发过程中,不同部门之间的协作效率直接影响项目的成败。集成产品开发(IPD)作为一种系统化的项目管理方法,旨在通过优化流程和增强团队协作来提升产品开发的效率和质量。然而,跨部门沟通的复杂性往往成为IPD实施中的一大挑战。部门之间的目标差异、信息不对称以及沟通渠道不畅...
IPD是什么意思   66  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用