如何使用 bash 命令将 csv 转换为二进制文件?

JVE*_*999 3 csv bash binaryfiles

我有一个csv文件,它只是一个简单的逗号分隔的数字列表。我想将此csv文件转换为二进制文件(只是一个字节序列,每个解释的数字都是csv文件中的一个数字)。

我这样做的原因是能够从值的电子表格中导入音频数据。在我的导入中(我使用的是 audacity),我有几种格式可供选择用于二进制文件:

Encoding:
Signed 8, 24, 16, or 32 bit PCM
Unsigned 8 bit PCM
32 bit or 64 bit float
U-Law
A-Law
GSM 6.10
12, 16, or 24 bit DWVW
VOX ADPCM

Byte Order:
No endianness
Big endian
Little endian
Run Code Online (Sandbox Code Playgroud)

我正在沿着big endian 32-bit float使事情简单的路线前进。我想让事情尽可能简单,所以我认为bash这是最佳工具。

Dum*_*001 5

我有一个csv文件,它只是一个简单的逗号分隔的数字列表。我想将此csv文件转换为二进制文件 [...]

我正在沿着big endian 32-bit float使事情简单的路线前进。

不确定如何以纯方式进行bash(实际上怀疑它是否可行,因为作为二进制浮点数是非标准转换)。

但这里有一个简单的 Perl 单行:

$ cat example1.csv
1.0
2.1
3.2
4.3

$ cat example1.csv | perl -ne 'print pack("f>*", split(/\s*,\s*/))' > example1.bin

$ hexdump -C < example1.bin
00000000  3f 80 00 00 40 06 66 66  40 4c cc cd 40 89 99 9a  |?...@.ff@L..@...|
00000010
Run Code Online (Sandbox Code Playgroud)

它使用 Perl 的pack 函数withf将浮点数转换为二进制,<并将它们转换为 BE。(我还添加了拆分,以防每个 CSV 行有多个数字。)

PS 将整数转换为具有本机字节序的 16 位 short 的命令:

perl -ne 'print pack("s*", split(/\s*,\s*/))'
Run Code Online (Sandbox Code Playgroud)

使用"s>*"的是或"s<*"为LE,而不是"s*"

PPS 如果是音频数据,也可以查看sox工具。很久没有使用它了,但是 IIRC 它可以将任何类似 PCM 的格式从任何格式转换为任何格式,同时还可以应用效果。

  • 你可以只使用 `&lt;input.txt perl -pe 'code' &gt;output.txt` (2认同)