【问题标题】:"tailing" a binary file based on string location using bash?使用 bash 根据字符串位置“拖尾”二进制文件?
【发布时间】:2023-03-21 01:20:01
【问题描述】:

我有一堆二进制文件,每个文件都在文件末尾附近包含一个嵌入的字符串,但在不同的位置(每个文件中只出现一次)。我需要提取从字符串位置开始直到文件末尾的文件部分并将其转储到一个新文件中。

例如。如果文件内容是“AWREDEDEDEXXXERESSDSDS”,感兴趣的字符串是“XXX”,那么我需要的文件部分就是“XXXERESSDSDS”。

在 bash 中最简单的方法是什么?

【问题讨论】:

    标签: bash tail string-search


    【解决方案1】:

    在PERL中,有一个内建的变量专门指匹配正则表达式之后的字符串部分。那将是我将使用的方法。不只是 Bash 和实用程序,还有 PERL 安装得非常普遍,您应该没问题。

    【讨论】:

    • unix 标准命令行中的大多数面向文本的实用程序处理二进制数据的效果不佳和/或不正确,因为它们会假设文件中没有“\0”字符。这就是为什么使用 Perl 或 Python 这样没有这些限制的程序会取得更大成功的原因。
    【解决方案2】:

    以下是一个性能不高的小型 hack shell 解决方案。但它有效。

    编写脚本文件tail.sh如下:

    #!/bin/sh
    dd bs=1 if=$1 of=$2 skip=`grep --binary-files=text -m1 -b -o $3 $1 | cut -d ':' -f 1 | head -1`
    

    调用tail.sh INPUTNAME OUTPUTNAME PATTERN

    ps:抱歉,在第一篇文章中忘记了一个 grep 选项

    【讨论】:

    • 给我这个错误:“dd: invalid number `'”。顺便说一句,这是在一个测试文件上。我让它在一个 9mb 的文件上运行了几分钟,但没有完成。
    • 正如我所说,它非常慢。由于 grep 无法正常工作,因此可能对您来说更慢。最好再试一次。
    【解决方案3】:

    你想要stringsgrep 吗?

    例如

    strings -n 3 myfilename | grep XXX
    

    【讨论】:

    • 它只返回字符串,而不是后面的位。我需要从字符串开头到文件结尾的所有内容。
    【解决方案4】:
     strings -n3 file_binary | awk '/XXX/{gsub(/.*XXX/,"");print}'
    

    【讨论】:

    • 在我的系统上打印一个空行。
    • 这个输出在下一个换行符处停止!
    • ...awk '/XXX/{gsub(/.*XXX/,"");p=1}p{print}'
    【解决方案5】:

    我想出了这个解决方案:

    ls -1 *.bin | xargs strings -n4 --radix=d -f | grep "string" | awk '{sub(/:/, ""); print $2 " " $1 " " $1".";}' | xargs -l1 split -b && rm *.aa
    

    ls -1 *.bin 仅以列表格式打印扩展名为“bin”的文件名

    xargs strings -n4 --radix=d -f 列出文件中的所有字符串及其位置,并在输出中包含文件名

    grep "string" 打印包含“string”的行(每个文件只出现一次)

    awk '{sub(/:/, ""); print $2 " " $1 " " $1".";}' 去掉字符串添加的文件名后面的冒号,打印字符串的位置、文件名、文件名用句点(这个line 用作 split 命令的参数

    xargs -l1 split -b 使用 awk 的输出作为其余参数为每一行执行 split 命令

    rm *.aa 删除分割文件的第一部分。 “aa”是分割文件部分的默认后缀。

    可能有更好/更快/更安全的方法来做这件事,但对我来说没问题。

    【讨论】:

      【解决方案6】:

      试试这个:

      grep -ao string.* filename
      

      由于您有二进制数据,您可能希望将输出重定向到文件。

      grep -ao string.* filename > binary.out
      

      或者通过hexdump 或类似的管道进行测试:

      grep -ao string.* filename | hd
      

      【讨论】:

      • 谢谢,不过遇到换行符时会失败。
      • 这个输出在下一个换行符处停止!
      猜你喜欢
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 1970-01-01
      • 2016-01-15
      • 1970-01-01
      • 2011-02-28
      • 2016-08-30
      相关资源
      最近更新 更多