【问题标题】:how to split a file into smaller files (one file per line) [split doesn't work]如何将文件拆分为较小的文件(每行一个文件)[拆分不起作用]
【发布时间】:2013-10-04 14:36:36
【问题描述】:

我正在尝试将一个非常大的文件拆分为每行一个新文件。

为什么?它将作为 Mahout 的输入。但行数过多,后缀不足,无法拆分。

有没有办法在 bash 中做到这一点?

【问题讨论】:

  • 我刚刚尝试过没有任何参数的拆分。 bash 的新手,所以在尝试。拆分 --lines=1 文件.txt

标签: bash split


【解决方案1】:

通过拆分增加后缀长度

如果你坚持使用拆分,那么你必须增加你的后缀长度。例如,假设您的文件中有 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。

【讨论】:

  • 你假设每一行都是独立访问的。完全有可能输入程序真的需要数千个独立的文件,它们都位于磁盘上,可以随机访问。
  • 这很酷,我如何使用 xargs 说一次打印一行?
  • 刚刚试过 xargs --max-lines=1 --arg-file=foo.txt echo 但由于某种原因只打印文件的前两行...
  • @user1745713 echo 可能是一个内置的shell。它对我来说是xargs --max-lines=1 --arg-file=foo.txt /bin/echo。请注意二进制文件的路径,而不是使用内置的 shell。
【解决方案2】:
split --lines=1 --suffix-length=5 input.txt output.

这将使用每个后缀 5 个字符,这对于 265 = 11881376 个文件来说已经足够了。如果你真的有更多,增加后缀长度。

【讨论】:

  • 快速跟进。您可以通过在输出上添加路径来指定输出目录不同,如下所示: split --lines=1 --suffix-length=5 input.txt output/file.
  • 是的,这行得通。 split 将使用您键入的任何前缀作为文字字符串。输出目录在运行 split 之前应该存在。
【解决方案3】:

下面是另一种为每一行做某事的方法:

while IFS= read -r line; do
    do_something_with "$line"
done < big.file

【讨论】:

    【解决方案4】:

    GNU Parallel 可以做到这一点:

    cat big.file | parallel --pipe -N1 'cat > {#}'
    

    但如果 Mahout 可以从标准输入读取,那么您可以避免临时文件:

    cat big.file | parallel --pipe -N1 mahout --input-file -
    

    了解更多关于 GNU Parallel https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1 并浏览教程:http://www.gnu.org/software/parallel/parallel_tutorial.html

    【讨论】:

      猜你喜欢
      • 2013-07-31
      • 1970-01-01
      • 2019-10-02
      • 1970-01-01
      • 2012-06-26
      • 2019-01-24
      • 2012-06-06
      • 2011-07-13
      • 1970-01-01
      相关资源
      最近更新 更多