如何将一个文件分割成多个小文件(每行一个文件)【split无法使用】

3

我想将一个非常大的文件分割成每行一个新文件。

为什么?因为这将作为Mahout的输入。但是行数太多,而分割后缀不足。

有没有办法在bash中实现这个功能?


我刚刚尝试了没有任何参数的split命令。对bash不熟悉,正在进行实验。split --lines=1 file.txt - user1745713
4个回答

4

使用split函数增加后缀长度

如果您坚持使用split函数,则必须增加后缀长度。例如,假设您的文件中有10,000行:

split --suffix-length=5 --lines=1 foo.txt

如果您想要更加灵活地使用这种方法,可以使用wc命令和一些Shell算术来动态设置后缀长度。例如:

file='foo.txt'
split \
    --suffix-length=$(( $(wc --chars < <(wc --lines < "$file")) - 1 )) \
    --lines=1 \
    "$file"

使用xargs代替

然而,上述方法只是一种应急方案。更正确的解决方法是使用GNU findutils包中的xargs命令,以每行一次的方式调用某些命令。例如:

xargs --max-lines=1 --arg-file=foo.txt your_command

这会逐行传输到您的命令。这是一种更加灵活的方法,将大大减少您的磁盘I/O。


你在假设每一行都可以独立访问。但实际上,输入的程序可能需要成千上万个独立的文件,它们都存在于磁盘上,并且需要随机访问。 - Ross Presser
这很酷,我怎样使用xargs来逐行打印输出? - user1745713
刚刚尝试了 xargs --max-lines=1 --arg-file=foo.txt echo,但由于某些原因只打印了文件的前两行... - user1745713
@user1745713 echo 可能是一个 shell 内置命令。对我来说,它的工作方式是 xargs --max-lines=1 --arg-file=foo.txt /bin/echo。请注意使用二进制文件的路径而不是使用 shell 内置命令。 - Todd A. Jacobs

2
split --lines=1 --suffix-length=5 input.txt output.

这将使用每个后缀5个字符,足以容纳265 = 11881376个文件。如果您的文件数量超过了这个限制,请增加后缀长度。


快速跟进。您能否通过在输出中添加路径来指定不同的输出目录,例如:split --lines=1 --suffix-length=5 input.txt output/file. - user1745713
是的,那会起作用。split将使用您键入的任何前缀作为字面字符串。在运行split之前,输出目录应该存在。 - Ross Presser

1
这是另一种针对每一行执行某些操作的方法:
while IFS= read -r line; do
    do_something_with "$line"
done < big.file

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接