我有一个程序在bash中处理for循环中的许多数据文件。目前,我需要将每个循环步骤输出到一个单独的文件,然后在最后再次处理所有这些文件,以便将它们制成表格。我想避免通过文件执行此操作的步骤,并使用基本的shell命令来执行此操作。这似乎应该是可能的,但我已经碰到了一堵砖墙。以下是一个示例,说明了粗略的过程:
#create some example data
seq 1 100 > results-all
split -l 10 -d -a 1 results-all results-
#process the data
for RESULT in `seq 0 9`; do tail -n-5 results-$RESULT > results-clean-$RESULT; done; paste results-clean-{0..9}
请记住,这是一个例子,实际上我对这些输入文件进行了更多的处理,因此过度简化的解决方案将该步骤转移到其他位置/以某种方式移除不太可能在实践中起作用(这是只是一个例子)。当我尝试更改此代码以删除通过文件的中间步骤时,我失去了粘贴以将输入格式化为列的能力。因此:
for RESULT in `seq 0 9`; do tail -n-5 results-$RESULT; done | paste - - - - - - - - - -
现在输出是按行而不是按列。我可以转置这些数据,但似乎并不是一个shell工具。我可以编写代码来对此进行转置(或者从Stack Overflow中复制一个示例来执行此操作),但似乎应该有一种方法来执行此操作而不诉诸于此。
非常感谢任何帮助。
答案 0 :(得分:0)
也许您可以使用-s
的{{1}}选项?
呃......不,不会工作。我们有paste
实用程序:
column
但有趣的是,数字或列输出是由当前终端的宽度控制的! : - /
for RESULT in `seq 0 9`; do tail -n-5 results-$RESULT; done | column -c100
可以帮助我生成所需的输出,但我想这也取决于系统上标准制表的长度......
好的,所以OP想要的是column -c100
的行为,一只猫告诉它输出矩阵的行数高度,无论终端的大小如何。我向column
添加了-h numrows
个选项,原始的column
来自BDSutils(我的Debian上的数据包 bsdmainutils )。
请找my modified version there。只需编译:
column
然后运行:
cc -o column column.c
获取高度为5的列。此选项与在另一个方向(即按行)填充矩阵的for RESULT in `seq 0 9`; do tail -n-5 results-$RESULT; done | /path/to/new/column -h5
标志兼容。
答案 1 :(得分:0)
这里的解决方案是使用读取和多个文件描述符进行输入。
编辑:我找到了一种自动化文件描述符分配的方法:在exec中保存它们。
for FDNR in `seq 0 9`; do eval exec "{fd$FDNR}<results-$FDNR"; done
while read -u $fd0 FILELINE ; do
echo -n $FILELINE
for FDNR in `seq 1 9`; do
otherfd=fd$FDNR
read -u ${!otherfd} FILELINE;
echo -n -e \\t$FILELINE
done
echo
done
for FDNR in `seq 0 9`; do eval exec "{fd$FDNR}<&-"; done
一般的想法是将每个输入分配给一个自己的文件描述符,然后从不同的文件描述符中读取一个循环,每个文件的一行并将其输出(由选项卡分隔)。在你输出一行文件之后,你做一个空的回显去下一行(在用-n压制之前)。