sed 捕获所有内容,直到使用变量作为字符串的模式
sed capture everything until pattern using variable as string
我有一堆表示类似于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 , not stripped) 它将文件作为参数并对其进行解码。
我可以成功运行:
./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。
我的主要目标是提取十六进制地址之前的所有内容,然后 运行 另一个命令在另一个方向复制相同的内容,如果您愿意的话,我只剩下大部分完整的“框架”。然后我可以根据帧大小对它进行尾部处理,这样它只包含一个完整的帧。
./application /tmp/file | sed "/$value/q"
研究shell中的引用以及单引号和双引号的区别。
要解析 XML 文件,请使用 XML 感知工具,例如 xmlstarlet。不要用正则表达式解析 XML。
不要使用 ` 反引号 - 请改用 $(...)
。
您的命令替换(反引号)在硬(单)引号 ('
) 内,因此 shell 不会扩展它。您也不需要 echo
,只需要变量本身。对于要扩展的变量,您仍然必须使用软(双)引号 ("
)。
hex='AB CD 34 43'
./application /tmp/file | sed "/$hex/q"
在sed
地址中使用shell变量时,请记住它是正则表达式,而不是字符串,并且sed
没有像[=19=这样的选项] 的 -F
(这样的选项对 sed
的 //{};
等也没有帮助 - 唯一的选择是事先逃脱)。对于十六进制没问题,因为它只有字母数字和 space 个字符。
此外,如您所说,sed
将打印到包含该模式的 行 。因此,在同一行上 模式之后的任何文本都将被包括在内。也许这可以满足您的要求,但我将提供一些方法来准确打印(并包括)图案,但不会再多了。
sed
sed -E "/$hex/{s/($hex)(.*)//;q}"
awk
awk -v RS="$hex" '{print([=12=] RS); exit}'
注意:POSIX 表示 RS
应该是单个字符,但许多实现接受正则表达式*
shell
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 as a regular expression [is a gawk extension]
mawk has allowed RS to be a regexp for decades. As of October, 2019, BWK awk also supports it.
如果模式 $hex
出现不止一次,这些都会打印到第一次出现的 $hex
(包括它),但可以轻松修改以打印到最后一次出现。
最后,当做这样的事情时,请记住 hexdump
实用程序可以使用 printf
之类的格式字符串来控制输出格式。例如 hexdump -ve '1/1 "%02x "' mybinfile; echo
以十六进制转储 space 分隔的字节列表 mybinfile
。
我有一堆表示类似于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 , not stripped) 它将文件作为参数并对其进行解码。
我可以成功运行:
./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。
我的主要目标是提取十六进制地址之前的所有内容,然后 运行 另一个命令在另一个方向复制相同的内容,如果您愿意的话,我只剩下大部分完整的“框架”。然后我可以根据帧大小对它进行尾部处理,这样它只包含一个完整的帧。
./application /tmp/file | sed "/$value/q"
研究shell中的引用以及单引号和双引号的区别。
要解析 XML 文件,请使用 XML 感知工具,例如 xmlstarlet。不要用正则表达式解析 XML。
不要使用 ` 反引号 - 请改用 $(...)
。
您的命令替换(反引号)在硬(单)引号 ('
) 内,因此 shell 不会扩展它。您也不需要 echo
,只需要变量本身。对于要扩展的变量,您仍然必须使用软(双)引号 ("
)。
hex='AB CD 34 43'
./application /tmp/file | sed "/$hex/q"
在sed
地址中使用shell变量时,请记住它是正则表达式,而不是字符串,并且sed
没有像[=19=这样的选项] 的 -F
(这样的选项对 sed
的 //{};
等也没有帮助 - 唯一的选择是事先逃脱)。对于十六进制没问题,因为它只有字母数字和 space 个字符。
此外,如您所说,sed
将打印到包含该模式的 行 。因此,在同一行上 模式之后的任何文本都将被包括在内。也许这可以满足您的要求,但我将提供一些方法来准确打印(并包括)图案,但不会再多了。
sed
sed -E "/$hex/{s/($hex)(.*)//;q}"
awk
awk -v RS="$hex" '{print([=12=] RS); exit}'
注意:POSIX 表示 RS
应该是单个字符,但许多实现接受正则表达式*
shell
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 as a regular expression [is a gawk extension]
mawk has allowed RS to be a regexp for decades. As of October, 2019, BWK awk also supports it.
如果模式 $hex
出现不止一次,这些都会打印到第一次出现的 $hex
(包括它),但可以轻松修改以打印到最后一次出现。
最后,当做这样的事情时,请记住 hexdump
实用程序可以使用 printf
之类的格式字符串来控制输出格式。例如 hexdump -ve '1/1 "%02x "' mybinfile; echo
以十六进制转储 space 分隔的字节列表 mybinfile
。