split -nr/$(wc -w <(head -1 input) | cut -d' ' -f1) -t' ' --additional-suffix=".txt" -a4 --numeric-suffix=1 --filter "cat <(echo -e 's=5 r=9') - | tr ' ' '\n' >\$FILE" <(tr -s '\n' ' ' <input) file
这以独特的方式使用漂亮的split 命令重新排列列。希望它比awk 更快,尽管在花费大量时间对其进行编码、测试和编写之后,我发现它可能对您来说不够可扩展,因为它需要每列一个进程,而且许多系统都是受限于用户进程(检查ulimit -u)。我提交它是因为它可能对您或未来的读者有一些有限的学习用处。
解码:
split -- 将文件分成子文件。通常这是按行或按大小,但我们正在调整它以使用列。
-nr/$(...) -- 使用循环输出:以循环方式将记录(在我们的例子中,矩阵单元)排序到适当数量的箱中。这是完成这项工作的关键。 parens 中的部分表示,计算(wc)输入的第一行(<(head -1 input))中的字数(-w)并丢弃文件名(cut -d' ' -f1),并将输出插入到命令中行。
-t' ' -- 使用单个空格作为记录分隔符。这会将矩阵单元格拆分为 split 的记录以进行拆分。
--additional-suffix=".txt" -- 将.txt 附加到输出文件。
-a4 -- 使用四位数字;您可能不会从中获得 1,000 个文件,但以防万一……
--numeric-suffix=1 -- 添加数字后缀(通常是字母组合)并从 1 开始。这很迂腐,但与示例匹配。如果您有超过 100 列,则需要添加 -a4 选项或您需要的任何长度。
--filter ... -- 通过 shell 命令对每个文件进行管道传输。
外壳命令:
cat -- 连接接下来的两个参数。
<(echo -e 's=5 r=9') -- 这意味着执行 echo 命令并将其输出用作cat 的输入。我们使用空格而不是换行符来分隔,因为我们最终会将空格转换为换行符,而且它更短且更易于阅读。
- -- 读取标准输入作为cat 的参数 -- 这是分箱数据。
| tr ' ' '\n' -- 根据所需的输出示例,将记录之间的空格转换为换行符。
>\$FILE -- 写入输出文件,该文件存储在$FILE 中(但我们必须引用它,以便 shell 不会在初始命令中解释它)。
Shell 命令结束 -- split 参数的其余部分:
<(tr -s '\n' ' ' < input) -- 使用示例输入文件作为split 的输入,但将换行符转换为空格,因为我们不需要它们并且我们需要一致的记录分隔符。 -s 表示每条记录之间只输出一个空格(以防我们在输入时有多个空格)。
file -- 这是输出文件名的前缀。我的示例中的输出将是file0001.txt、file0002.txt、...、file0005.txt。