使 sed 正则表达式交替遵循从左到右的优先顺序?

Make sed regex alternations follow left to right precedence?

我正在尝试使用正则表达式来格式化来自 xxd -b 的一些二进制文件,但为了简单地演示这一点,我将向您展示我期望发生的事情:

要删除的正则表达式:/1x|1.*/

文本:1x21y3333333313333 -> 2

在删除所有出现的 1x 的情况下,应删除从出现的第一个 1 开始的所有内容。应该立即清楚发生了什么,但如果不是,play with this。关键是如果 1x 被匹配,模式的其余部分应该被中止。

这是 echo "AA" | xxd -b 的输出(AA\n 的绑定转储):

0000000: 01000001 01000001 00001010                             AA.

我的目标是 1. 删除每个字节(ascii = 7 位)的第一个 0 和 2. 删除字符串的其余部分,以便只保留实际的二进制文件。所以我把它传送到 sed 's/ 0//g':

0000000:100000110000010001010                             AA.

添加第二步,sed -E 's/ 0| .*//g':

0000000:

显然,我希望得到:

0000000:100000110000010001010

我尝试过但还没有完成的事情:

在此期间我将改用 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'