如何“逆转” cat -A?

如何“逆转” cat -A?

考虑以下:

$ cat -A input.txt
Hello^IWorld$
newline$

这里,cat -A采用实际的换行符和制表符(即真实字符),并将它们转换为表示形式。

Ubuntu 存储库中是否有 shell 方式或命令行应用程序可以允许获取不可打印字符的表示并输出真实的价值观 ?

从某种意义上说,我在问是否存在类似于的东西$'Hello\tWorld\nnewline\n',只不过我想使用“shell 引用”字符串而不是 C 引用的字符串。

答案1

那么,Python 来救援了!

查看此单行代码,它从 STDIN 读取并打印到 STDOUT,处理所有可能的“插入符号转义”/“C0 代码”(如^I)和行尾指示符($):

python3 -c 'import sys,re;print(re.sub(r"\^([A-Z?@[\\\]^_])",lambda m:chr((ord(m.group(1))-64)&127),sys.stdin.read().replace("$\n","\n")))'

实际上它与python(2) 和都兼容python3。下面是一个更长、更易读的版本,基本上做了同样的事情:

#!/usr/bin/env python3
import sys, re

# read everything from stdin and remove line-end indicators
s = sys.stdin.read().replace("$\n", "\n"))

# replace caret escapes like ^I or ^M and output to stdout
print(re.sub(r"\^([A-Z?@[\\\]^_])", lambda m: chr((ord(m.group(1)) - 64) & 127), s)

因此,我们首先删除行尾指示符$

其次,我们使用正则表达式模式\^([A-Z?@[\\\]^_])查找插入符号后面的所有有效字符,并将其替换为正确的未转义字符,根据维基百科插入符号C0 控制代码。请注意,只有大写字母A-Z或其中一个?@[\]^_具有特殊含义。

现在,为了取消转义这样的 C0 代码,我们取插入符号后面的字符在字母表中的位置(在 中找到m.group(1)),例如“A”为 1,“B”为 2,依此类推。这等于其 ASCII 值减去“A”的 ASCII 码加一,即 -64,这也解释了例如“@”(ASCII 64)为 0 或“[”(ASCII 91)为 ESC(ASCII 27)。我们对这个数字与 127 进行二进制 AND 运算,只考虑前 7 位信息,因此例如“?”(ASCII 63 == 64-1)会折回为 127,表示 DEL 字符。

最后,经过所有这些高度复杂计算完成后,我们只需将结果字符串再次打印到 STDOUT。

相关内容