【问题标题】:sed capture everything until pattern using variable as stringsed 捕获所有内容,直到使用变量作为字符串的模式
【发布时间】:2021-09-05 17:58:06
【问题描述】:

我有一堆类似于 xml 的文本。

<File>
    <abc1>
        <Hex>
            <item>
                <data>AB CD 34 43</data>
            </item>
         </Hex>
    </abc1>
</File>

我使用一个应用程序(ELF 64 位 LSB 可执行文件,x86-64,版本 1 (SYSV),动态链接,解释器 /lib64/ld-linux-x86-64.so.2,用于 GNU/Linux 2.6。 32,未剥离),它将文件作为参数并对其进行解码。

我可以成功运行:

./application /tmp/file and it decodes correctly

我还可以捕获所有内容,包括包含下面十六进制的行(这很好用,但当然,不能将所有数据都输入文件然后运行它 - 需要动态地使用变量来完成:

./application /tmp/file | sed '/AB CD 34 43/q'

但我无法做的是传递一个变量而不是十六进制字符串

./application /tmp/file | sed '/`echo -n "$value"`/q'

我不介意我使用什么,sed/awk/grep。

我的主要目标是将所有内容提取到十六进制地址,然后运行另一个命令以在另一个方向复制相同的内容,如果您愿意的话,我只剩下一个完整的“框架”。然后我可以根据帧大小将它拖尾,这样它就只包含一个完整的帧。

【问题讨论】:

  • 谢谢@KamilCuk 我认为你是对的。令人沮丧,因为我快到了,但最好让它正确,xmlstarlet 可能有更简单的方法,谢谢先生!

标签: variables awk sed grep echo


【解决方案1】:
./application /tmp/file | sed "/$value/q"

研究shell中的引用以及单引号和双引号的区别。

要解析 XML 文件,请使用 XML 感知工具,例如 xmlstarlet。不要使用正则表达式解析 XML。

不要使用 ` 反引号 - 改用 $(...)

【讨论】:

    【解决方案2】:

    您的命令替换(反引号)在硬(单)引号(')内,因此 shell 不会扩展它。你也不需要echo,只需要变量本身。您仍然必须使用软(双)引号 ("),才能扩展变量。

    hex='AB CD 34 43'
    
    ./application /tmp/file | sed "/$hex/q"
    

    sed 地址中使用shell 变量时,请记住它是正则表达式,而不是字符串,并且sed 没有像grep-F 这样的选项(也没有这样的选项帮助sed//{}; 等 - 唯一的选择是事先逃跑)。十六进制没问题,因为它只有字母数字和空格字符。

    另外,正如您所说,sed 将打印到包含该模式的 。因此,在同一行上的模式之后 的任何文本都将被包括在内。也许这可以满足您的要求,但我将包括一些打印(并包括)该模式的方法,但仅此而已。

    sed

    sed -E "/$hex/{s/($hex)(.*)/\1/;q}"
    

    awk

    awk -v RS="$hex" '{print($0 RS); exit}'
    

    注意:POSIX 说 RS 应该是单个字符,但许多实现都接受正则表达式*

    外壳

    decoded=$(./application /tmp/file)
    truncated=${decoded%%"$hex"*}
    echo "$truncated"
    

    这首先将所有数据复制到内存中,对于非常大的数据可能会很慢,但对于小数据,b/c 纯 shell 会很快。引用 $hex 将其视为字符串而不是模式。

    * 来自https://www.gnu.org/software/gawk/manual/html_node/gawk-split-records.html

    RS 作为正则表达式 [是一个 gawk 扩展]

    几十年来,mawk 让 RS 成为一个正则表达式。截至 2019 年 10 月,BWK awk 也支持它。

    如果模式$hex 出现不止一次,这些都会打印到$hex(包括它)的第一次出现,但可以很容易地修改为打印到最后一次出现。

    最后,在做这样的事情时,请记住hexdump 实用程序可以使用printf 之类的格式字符串来控制输出格式。例如,hexdump -ve '1/1 "%02x "' mybinfile; echo 以十六进制形式转储mybinfile 中以空格分隔的字节列表。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-16
      • 1970-01-01
      • 2023-04-02
      • 2015-04-18
      • 2018-12-11
      • 2021-12-01
      相关资源
      最近更新 更多