让 sed 正则表达式更改遵循从左到右的优先级?



我正在尝试使用正则表达式来格式化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'

最新更新