Bash 在多行上查找并替换精确匹配的十六进制

Bash 在多行上查找并替换精确匹配的十六进制,bash,perl,awk,sed,Bash,Perl,Awk,Sed,我正试图找到一种找到/匹配模式的方法 2f 34 2e 30 20 28 63 6f 并将其替换为 2f 35 2e 30 20 28 68 63 问题是这种模式可以用许多不同的方式在两行上分解,例如,2f 34 2e 30 20可以在第一行的末尾,然后在下一行上分解模式的其余部分。我想学习如何找到一个替代其他(更大的)模式 只有当模式完全包含在一行中时,此代码才有效 # replace hex equivalent of "/4.0 (co" with "/5.0 (hc" in hex

我正试图找到一种找到/匹配模式的方法

2f 34 2e 30 20 28 63 6f
并将其替换为

2f 35 2e 30 20 28 68 63
问题是这种模式可以用许多不同的方式在两行上分解,例如,
2f 34 2e 30 20
可以在第一行的末尾,然后在下一行上分解模式的其余部分。我想学习如何找到一个替代其他(更大的)模式

只有当模式完全包含在一行中时,此代码才有效

# replace hex equivalent of "/4.0 (co" with "/5.0 (hc" in hex field
sed 's/2f 34 2e 30 20 28 63 6f/2f 35 2e 30 20 28 68 63/g' <MPFADT$var.txt >>MPFADT$new.txt"

您用来生成十六进制转储文件的工具可以使用多行打印十六进制代码,但原始文件中包含的十六进制字符串不会“断开”为多行。我的意思是如果“2f 34 2e 30 20 28 63 6f”的某个地方有新行。。。这将是一个不同的十六进制序列

也就是说,我认为您可以使用sed:

$ sed 's/\x2f\x34\x2e\x30\x20\x28\x63\x6f/\x2f\x35\x2e\x30\x20\x28\x68\x63/' your_file

这里有一种方法不关心要替换的字符串的长度或拆分的行数:

$ cat tst.awk
{
    keys[NR] = $1
    sub(/^[^[:space:]]+[[:space:]]+/,"")
    buf = (NR>1 ? buf FS : "") $0
}
END {
    gsub(old,new,buf)
    for (i=1; i<length(buf); i+=(NF*3)) {
        print keys[++nr] "  " substr(buf,i,(NF*3)-1)
    }
}

$ awk -v old="2f 34 2e 30 20 28 63 6f" -v new="2f 35 2e 30 20 28 68 63" -f tst.awk file
0070  41 67 65 6e 74 3a 20 4d 6f 7a 69 6c 6c 61 2f 35
0080  2e 30 20 28 68 63 6d 70 61 74 69 62 6c 65 3b 20
$cat tst.awk
{
钥匙[NR]=$1
子(/^[^[:space:]+[:space:]+/,“”)
buf=(NR>1?buf FS:)$0
}
结束{
gsub(旧、新、buf)

对于(i=1;i这里有一种方法。首先使用
xxd
以普通格式转储文件,这将抑制左侧的地址。现在删除所有换行,这样就不能跨多行了,因为您的文件现在是一个长行,然后不受惩罚地进行替换,然后再次使用
xxd
重建。这需要It’描述的时间比描述的时间长

xxd -p input.bin | tr -d '\n' | sed 's/2f342e302028636f/2f352e3020286863/g' | xxd -r -p - patched.bin
您最好使用GNU sed,因为它对行长度没有限制。

这可能适合您(GNU sed):

保持两行和模式匹配的运行窗口。由于模式可能出现在输出中的任何位置,因此允许在每对符号之间提供备用模式

注意:你的成功可能有限,因为分页可能会打乱苹果的购物车

$ cat tst.awk
{
    keys[NR] = $1
    sub(/^[^[:space:]]+[[:space:]]+/,"")
    buf = (NR>1 ? buf FS : "") $0
}
END {
    gsub(old,new,buf)
    for (i=1; i<length(buf); i+=(NF*3)) {
        print keys[++nr] "  " substr(buf,i,(NF*3)-1)
    }
}

$ awk -v old="2f 34 2e 30 20 28 63 6f" -v new="2f 35 2e 30 20 28 68 63" -f tst.awk file
0070  41 67 65 6e 74 3a 20 4d 6f 7a 69 6c 6c 61 2f 35
0080  2e 30 20 28 68 63 6d 70 61 74 69 62 6c 65 3b 20
xxd -p input.bin | tr -d '\n' | sed 's/2f342e302028636f/2f352e3020286863/g' | xxd -r -p - patched.bin
sed -r 'N;s/2f(\n....  | )34(\n....  | )2e(\n....  | )30(\n....  | )20(\n....  | )28(\n....  | )63(\n....  | )6f/2f\135\22e\330\420\528\668\763/;P;D' file