我想对一个 20GB 的二进制文件进行排序,该文件包含以连续方式放置的 30 字节键和 20 字节值。一切都在一条线上。我想指定排序必须用于比较的键长度和记录大小。这样,当键移动时,与其关联的值也会移动。
理想情况下,我不想以任何方式修改文件(即在键和值之间添加分隔符)。该文件看起来像KVKVKVKVKVKV. 单行二进制文件。
20GB 文件的前 200B 的 Hexdump:
# hexdump -n 200 -C 20gbUnsorted
00000000 54 65 73 74 69 6E 67 31 32 33 65 08 00 60 83 6b |Testing123e..`.k|
00000010 39 2c d5 8b 8f 5e 55 96 18 55 e7 9b 87 f0 22 83 |9,...^U..U....".|
00000020 a4 66 b6 aa b1 f9 e0 ca cf 1e 26 b3 29 2a fd 10 |.f........&.)*..|
00000030 64 bb 18 b5 6a c0 7d 6f 65 6b 1d 2f 43 0d 57 bd |d...j.}oek./C.W.|
00000040 e7 e4 7d 81 f3 6a 6d d2 67 94 8b bc 23 97 bf e2 |..}..jm.g...#...|
00000050 8c 33 4e 4a d8 2b 8e 70 16 62 93 cf aa 01 16 bf |.3NJ.+.p.b......|
00000060 da 3b b1 ab 95 e0 e4 82 62 b3 ed fe 04 47 b5 7f |.;......b....G..|
00000070 77 b1 3a 35 87 fb e7 90 42 e3 c4 06 d6 8e 9f d2 |w.:5....B.......|
00000080 c7 f3 f6 39 0d 9d 0d ce 13 fb 83 42 e1 52 81 2e |...9.......B.R..|
00000090 99 4b 4b 40 3a 16 7a 2a 7c 93 c3 84 1d e1 93 0a |.KK@:.z*|.......|
000000a0 0d b2 07 f4 eb 9e 04 b5 9e d8 77 d9 a1 a0 67 a1 |..........w...g.|
000000b0 01 fa 8d 8d 4c 04 5b ee a3 00 6f b4 20 50 a4 e6 |....L.[...o. P..|
000000c0 5b b3 cc 40 83 eb b2 ad |[..@....|
000000c8
Run Code Online (Sandbox Code Playgroud)
我正在使用Linux。
这感觉很难看,但它应该有效:
hexdump -v -e '50/1 "%02x " "\n"' file.bin | sort | xxd -p -r > file-sorted.bin
Run Code Online (Sandbox Code Playgroud)
您hexdump按每行 50 个字节进行分组,对sort这些行执行普通操作,然后使用xxd -r.
我不关心仅对前 30 个字节进行排序,因为如果它们相同,则顺序是开放的,我选择继续按值排序。
IMO,用编程语言更容易管理,可以轻松读取/写入二进制文件。对于(一个深奥的)例子,Tcl:
\ntclsh <<\'END_TCL\'\n set fh [open file.bin rb]\n while {true} {\n set kv [read $fh 50]\n if {[string length $kv] != 50} break\n lappend kvs $kv\n }\n close $fh\n\n set fh [open file_sorted.bin wb]\n foreach kv [lsort $kvs] {puts -nonewline $fh $kv}\n close $fh\nEND_TCL\nRun Code Online (Sandbox Code Playgroud)\n这是输入文件:
\ntclsh <<\'END_TCL\'\n set fh [open file.bin rb]\n while {true} {\n set kv [read $fh 50]\n if {[string length $kv] != 50} break\n lappend kvs $kv\n }\n close $fh\n\n set fh [open file_sorted.bin wb]\n foreach kv [lsort $kvs] {puts -nonewline $fh $kv}\n close $fh\nEND_TCL\nRun Code Online (Sandbox Code Playgroud)\n以及输出文件:
\n$ ls -l file.bin\n-rw-r--r-- 1 glennj glennj 200 Apr 20 16:07 file.bin\n\n$ od -c -w50 file.bin\n0000000 T e s t i n g 1 2 3 e \\b \\0 ` 203 k 9 , \xef\xbf\xbd 213 217 ^ U 226 030 U \xef\xbf\xbd 233 207 \xef\xbf\xbd " 203 \xef\xbf\xbd f \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd 036 & \xef\xbf\xbd ) * \xef\xbf\xbd 020 d \xef\xbf\xbd\n0000062 030 \xef\xbf\xbd j \xef\xbf\xbd } o e k 035 / C \\r W \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd } 201 \xef\xbf\xbd j m \xef\xbf\xbd g 224 213 \xef\xbf\xbd # 227 \xef\xbf\xbd \xef\xbf\xbd 214 3 N J \xef\xbf\xbd + 216 p 026 b 223 \xef\xbf\xbd \xef\xbf\xbd 001 026 \xef\xbf\xbd \xef\xbf\xbd ; \xef\xbf\xbd \xef\xbf\xbd\n0000144 225 \xef\xbf\xbd \xef\xbf\xbd 202 b \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd 004 G \xef\xbf\xbd 177 w \xef\xbf\xbd : 5 207 \xef\xbf\xbd \xef\xbf\xbd 220 B \xef\xbf\xbd \xef\xbf\xbd 006 \xef\xbf\xbd 216 237 \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd 9 \\r 235 \\r \xef\xbf\xbd 023 \xef\xbf\xbd 203 B \xef\xbf\xbd R 201 . 231 K K @ : 026\n0000226 z * | 223 \xef\xbf\xbd 204 035 \xef\xbf\xbd 223 \\n \\r \xef\xbf\xbd \\a \xef\xbf\xbd \xef\xbf\xbd 236 004 \xef\xbf\xbd 236 \xef\xbf\xbd w \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd g \xef\xbf\xbd 001 \xef\xbf\xbd 215 215 L 004 [ \xef\xbf\xbd \xef\xbf\xbd \\0 o \xef\xbf\xbd P \xef\xbf\xbd \xef\xbf\xbd [ \xef\xbf\xbd \xef\xbf\xbd @ 203 \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd\n0000310\nRun Code Online (Sandbox Code Playgroud)\n出于好奇,我从这样的问题创建了输入文件(bash):
\n$ ls -l file_sorted.bin\n-rw-r--r-- 1 glennj glennj 200 Apr 20 16:11 file_sorted.bin\n\n$ od -c -w50 file_sorted.bin\n0000000 030 \xef\xbf\xbd j \xef\xbf\xbd } o e k 035 / C \\r W \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd } 201 \xef\xbf\xbd j m \xef\xbf\xbd g 224 213 \xef\xbf\xbd # 227 \xef\xbf\xbd \xef\xbf\xbd 214 3 N J \xef\xbf\xbd + 216 p 026 b 223 \xef\xbf\xbd \xef\xbf\xbd 001 026 \xef\xbf\xbd \xef\xbf\xbd ; \xef\xbf\xbd \xef\xbf\xbd\n0000062 T e s t i n g 1 2 3 e \\b \\0 ` 203 k 9 , \xef\xbf\xbd 213 217 ^ U 226 030 U \xef\xbf\xbd 233 207 \xef\xbf\xbd " 203 \xef\xbf\xbd f \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd 036 & \xef\xbf\xbd ) * \xef\xbf\xbd 020 d \xef\xbf\xbd\n0000144 z * | 223 \xef\xbf\xbd 204 035 \xef\xbf\xbd 223 \\n \\r \xef\xbf\xbd \\a \xef\xbf\xbd \xef\xbf\xbd 236 004 \xef\xbf\xbd 236 \xef\xbf\xbd w \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd g \xef\xbf\xbd 001 \xef\xbf\xbd 215 215 L 004 [ \xef\xbf\xbd \xef\xbf\xbd \\0 o \xef\xbf\xbd P \xef\xbf\xbd \xef\xbf\xbd [ \xef\xbf\xbd \xef\xbf\xbd @ 203 \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd\n0000226 225 \xef\xbf\xbd \xef\xbf\xbd 202 b \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd 004 G \xef\xbf\xbd 177 w \xef\xbf\xbd : 5 207 \xef\xbf\xbd \xef\xbf\xbd 220 B \xef\xbf\xbd \xef\xbf\xbd 006 \xef\xbf\xbd 216 237 \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd \xef\xbf\xbd 9 \\r 235 \\r \xef\xbf\xbd 023 \xef\xbf\xbd 203 B \xef\xbf\xbd R 201 . 231 K K @ : 026\n0000310\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
909 次 |
| 最近记录: |