如何确定具有固定大小记录的二进制文件中的记录数

如何确定具有固定大小记录的二进制文件中的记录数

我正在尝试确定二进制文件中的记录数。二进制文件的大小由 确定wc -c。分隔符未知。记录大小是固定的。每条记录的确切大小未知我想确定记录数

答案1

尝试这个:

script.sh

#!/bin/bash

# read filename to var f from $1
f="$1"
# quit if file not found.
[ -f "$f" ] || { >&2 echo "File not found." ; exit 2; }
# total length of file (-1 to not count newline at the end of a file)
n=$(($(wc -c < "$f")-1))
# loop potential length of records, end at half total length of file.
for i in $(seq 1 $(awk -v n=$n 'BEGIN{print int((n/2)+0.5)-1}')); do
    # now read all delimiters regarding record length from a file
    # (see https://unix.stackexchange.com/a/276957/236063)
    # and `sort -u` to get only individual ones
    c=$(for ((j=i;j<n;j=j+i+1)); do printf '%s\n' $(dd ibs=1 skip=$j count=1 < "$f" 2>/dev/null); done | sort -u)
    # if we have exactly one individual delimiter, we're done and can print length of record and the delimiter and exit.
    if [ $(echo "$c" | wc -l) -eq 1 ]; then
        printf 'l=%s d=%s\n' "$i" "$c"
        exit 0
    fi
done
>&2 echo "No delimiter found".
exit 1

内容file

abc,def,ghi

输出:

$ ./script.sh file
l=3 d=,

退出代码:

 0 success, found delimiter and record length
 1 no delimiter found
10 file not found

注意:我认为还需要做一些工作来解决一些问题,特别是关于换行符......

答案2

不知道记录(和分隔符)的确切大小使得这个问题无法用简单而优雅的解决方案来解决。

主要警告: 这可能是一种绝望的情况,因为可能根本没有分隔符(如果写入文件的软件知道记录大小,则不需要用分隔符分隔记录)或者整个文件可能是一条记录。此外,在某些情况下,在记录内被视为分隔符的字符之前可能有“转义字符”(不太可能使用固定的记录大小,但它会使情况变得更糟,分析起来),但“这取决于”。此外,二进制文件格式在实际记录开始之前可以有一个“标头”块,您需要知道它的大小才能工作。

但希望渺茫。由于记录的固定大小长度是确定的,那么 -假设没有标题- 文件的大小(通过 获得wc -c)必须是记录大小和记录数的乘积。

我们可以尝试暴力方法:

  1. 查找文件的大小wc -c(让其命名fileSize
  2. 求 的因数fileSize
  3. 找到所有因素的组合,这样您就可以获得适合文件的所有可能数量的记录。
  4. 检查字符结尾可能的记录大小。如果您发现假设的数字具有以相同字符结尾的记录,您可能会认为这是分隔符。

这并不是 100% 完美,但应该有助于进一步研究记录和文件。

例子:

文件内容:

abcxdefxabnxccdxdfaxaafx
  1. 文件大小:24字节

  2. 因数:factors 24: 2 2 2 3

  3. 可能的组合:

    • 2 x 12(两条记录,每条12字节)
    • 3×8
    • 4×6
    • 6×4
    • 8×3
    • 12×2
  4. 对于上面的每一种可能性,我们都有分隔符:

    • x
    • x
    • (不同的,所以不考虑这种情况)
    • x
    • (不同的)
    • (不同的)
  5. 我们可能会猜测这x是分隔符,最小可能的记录大小是 4 个字符,这符合情况。

这只是一个例子。你应该尝试不同的假设,如果文件很大,你可以使用另一种方法,比如找出两个相同字符之间的距离。

相关内容