我正在尝试使用正则表达式来格式化xxd -b
中的一些二进制文件,但为了简单地演示这一点,我将向您展示我期望发生的事情:
要删除的正则表达式:/1x|1.*/
文本:1x21y3333333313333
->2
如果删除所有出现的1x
,则应删除从显示的第一个 1 开始的所有内容。应该立即清楚发生了什么,但如果不是,那就玩这个。关键是,如果匹配1x
,则应中止模式的其余部分。
这是echo "AA" | xxd -b
的输出(AAn
的二进制转储):
0000000: 01000001 01000001 00001010 AA.
我的目标是 1. 删除每个字节的前 0(ASCII = 7 位)和 2. 删除字符串的其余部分,以便仅保留实际的二进制文件。所以我把它用管道sed 's/ 0//g'
:
0000000:100000110000010001010 AA.
添加第二步,sed -E 's/ 0| .*//g'
:
0000000:
显然,我希望得到:
0000000:100000110000010001010
我尝试过但尚未完成工作的事情:
xxd
可能需要-g0
来合并列,但它在每个字节中保留第一个零(每个字符占用一个字节,而不是 7 位)-r
在此期间,我将改用perl,但是这种行为让我感到困惑,也许这里有一个原因(教训)?
如果我正确理解您的问题,这将产生您想要的:
$ echo "AA" | xxd -b | sed -E 's/ 0| .*//g'
00000000:100000110000010001010
这里的关键更改是在.*
前面使用两个空白,以便这仅与要删除的部分匹配。
或者,我们可以先删除空白零:
$ echo "AA" | xxd -b | sed -E 's/ 0//g; s/ .*//'
00000000:100000110000010001010
尝试以下操作:
s/ 0| [^0].*//g
出现行为的原因是 POSIX 规则引擎遵循尽可能长的匹配标准。因此,只要交替的第二面比第一面长,即使是第二方,它就会更早匹配。
在 GNU sed 上尝试过
sed -E 's/s+(0|[a-z.]+)//ig'