【发布时间】:2013-10-04 14:36:36
【问题描述】:
我正在尝试将一个非常大的文件拆分为每行一个新文件。
为什么?它将作为 Mahout 的输入。但行数过多,后缀不足,无法拆分。
有没有办法在 bash 中做到这一点?
【问题讨论】:
-
我刚刚尝试过没有任何参数的拆分。 bash 的新手,所以在尝试。拆分 --lines=1 文件.txt
我正在尝试将一个非常大的文件拆分为每行一个新文件。
为什么?它将作为 Mahout 的输入。但行数过多,后缀不足,无法拆分。
有没有办法在 bash 中做到这一点?
【问题讨论】:
如果你坚持使用拆分,那么你必须增加你的后缀长度。例如,假设您的文件中有 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"
但是,无论如何,以上内容实际上只是一个杂项。更正确的解决方案是使用 GNU findutils 包中的 xargs 每行调用一次命令。例如:
xargs --max-lines=1 --arg-file=foo.txt your_command
这将一次将一行传递给您的命令。这是一种更加灵活的方法,将大大减少您的磁盘 I/O。
【讨论】:
xargs --max-lines=1 --arg-file=foo.txt /bin/echo。请注意二进制文件的路径,而不是使用内置的 shell。
split --lines=1 --suffix-length=5 input.txt output.
这将使用每个后缀 5 个字符,这对于 265 = 11881376 个文件来说已经足够了。如果你真的有更多,增加后缀长度。
【讨论】:
下面是另一种为每一行做某事的方法:
while IFS= read -r line; do
do_something_with "$line"
done < big.file
【讨论】:
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
【讨论】: