在 Bash 中将文件中的 n 个字节写入另一个文件

PiN*_*bie 13 linux file-management bash binary-files bash-scripting

您好,如何使用 Bash将n字节从一个文件写入新文件k

  • 例如,如果 n=60,k=1 并且文件大小=100,那么:第二个文件将由第一个字节到第 60 个字节组成,大小为 60 个字节
  • 例如,如果 n=40,k=61 和文件大小=100,那么:第二个文件将由第 61 个字节到第 100 个字节组成,大小为 40 个字节

可能我们正在处理二进制文件而不是 ASCII 文件,因此两半的连接应该与原始文件相同!

(有可能dd吗?)

cxw*_*cxw 14

是的。根据dd 手册页,您正在寻找类似的内容:

dd bs=1 count=60 if=_filename_1_ of=_filename_2_
dd bs=1 skip=60 count=40 if=_filename_1_ of=_filename_2_
Run Code Online (Sandbox Code Playgroud)

where_filename_n_替换为实际文件名。

bs=1意味着countskip是字节数。 skip是要跳过多少;count是复制多少。 编辑字节数从 0 开始,而不是 1。因此,要从第一个字节开始,请使用skip=0(或不skip指定)。

作为 bash 函数,您可以使用:

# copy_nk(n, k, infile, outfile)
copy_nk() {
    dd bs=1 count="$1" skip="$2" ${3:+if="$3"} ${4:+of="$4"}
}
Run Code Online (Sandbox Code Playgroud)

然后将其称为

copy_nk 60 0 infile.txt outfile.txt
Run Code Online (Sandbox Code Playgroud)

(使用 k=0因为字节数从零开始)。

使用${3:+...},您可以不使用输出文件或输入文件。例如,

cat infile.txt | copy_nk 60 0 > outfile.txt
Run Code Online (Sandbox Code Playgroud)


Dig*_*uma 9

这是使用headbash 命令组的另一种方法:

{ head -c60 > /dev/null ; head -c40 > output.txt ; } < input.txt
Run Code Online (Sandbox Code Playgroud)

第一次head在这里读取input.txt的第一个60个字节,并将其发送给位桶。

由于这些head命令在命令组内,因此将保留 input.txt 中的文件位置。因此,第二个head将读取接下来的 40 个字节(使用基于 1 的索引从字节 61 到 100),并将其写入 output.txt。


事实上,这种方法可以推广到split类似的功能,但具有能够指定每个输出文件的长度的额外好处。假设我们有一个 100 字节的文件,我们希望将其拆分为大小为 7、50、23 和其余大小的块。我们可以这样做:

{
    head -c7 > 7bytes.txt
    head -c50 > 50bytes.txt
    head -c23 > 23bytes.txt
    cat > remaining-bytes.txt
} < input.txt
Run Code Online (Sandbox Code Playgroud)

  • 如果您足够疯狂,可以将其输出通过管道传输到块设备,那么您可以同样轻松(或更容易)使用 `head` 破坏文件系统。当然,你不会那样做——你会使用 `dd` 来代替,或者其他适合这项工作的东西。`dd` 声名狼藉的原因是它足够强大,你*可以*或多或少地安全地将它用于本质上危险的任务,比如克隆磁盘映像,如果你足够小心的话。当然,有些人不会并且会弄乱他们的磁盘——但这样做的原因不是他们使用了 `dd`,而是他们首先弄乱了 `/dev/sda`。 (4认同)