如何分割特定大小的文件并将其传递给命名管道

如何分割特定大小的文件并将其传递给命名管道

我有一个大小为 2GB 的文件,想要分块读取并将每块传递给命名管道。

例如;

mkfifo /tmp/pipe
tail -c 200 myfile > /tmp/pipe &  #last 200 bytes of file in the pipe.
use the /tmp/pipe.

我想将一些固定已知大小的数据传递到命名管道,然后将该管道传递到 lftp。现在,一旦完成此操作,再次在管道中加载下一个字节并执行 lftp 操作。

如何从文件中读取 5MB(或任何大小,比如 x),然后将其传递给管道,然后使用该管道,然后继续到下一个 5MB 并继续,直到到达文件末尾。

答案1

一个简单的解决方案是使用split --filter=…

--filter=COMMAND
写入 shell COMMAND;文件名为$FILE

来源

--filter选项不可移植,希望您split支持它。GNU splitcoreutils 支持。该选项接受 shell 命令。我对 GNU 的测试表明该工具使用在(或如果未设置)split中指定的 shell 。$SHELLsh

shell 命令可能非常复杂。或者,您可以调用任意复杂的脚本 ( --filter=/path/to/script.sh)。该命令或脚本将为每个片段调用一次,片段将通过其 stdin 进入。如果您可以从 stdin 读取,则不需要额外的(命名)管道。

如果你的操作系统提供了/dev/stdin,那么我相信在你的情况下 shell 命令可能是:

lftp … -e "put /dev/stdin -o $FILE"

您应该将其中的内容替换为服务器地址,以及满足您需求的其他内容。我承认我只是粗略地测试了该命令,它来自这个答案

你的split命令将如下所示:

split -b 5242880 --filter='
   lftp … -e "put /dev/stdin -o prefix-$FILE"
' myfile

注意$FILE不能由本地 shell 扩展,它应该是单引号(并且它是,请参阅这个问题)。将使用环境中split的正确相应值运行内壳。内壳的上下文中不能使用单引号。$FILE$FILE

该命令将在服务器上创建名称以 开头的文件prefix-。除非当地语言环境很奇怪,否则名称将按应有的方式排序,因此此命令:

cat prefix-* > myfile

在服务器上的 shell 中调用(在本地split成功发送所有片段后)将在那里创建原始文件的副本。如果您怀疑语言环境很奇怪(或者您只是想保险起见),请使用:

(LC_COLLATE=C; cat prefix-* > myfile)

相关内容