输入来自管道时,按列输出粘贴

时间:2014-08-07 07:37:28

标签: bash shell

我有一个程序在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中复制一个示例来执行此操作),但似乎应该有一种方法来执行此操作而不诉诸于此。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

也许您可以使用-s的{​​{1}}选项?

呃......不,不会工作。我们有paste实用程序:

column

但有趣的是,数字或列输出是由当前终端的宽度控制的! : - /

修改

for RESULT in `seq 0 9`; do tail -n-5 results-$RESULT; done | column -c100 可以帮助我生成所需的输出,但我想这也取决于系统上标准制表的长度......

EDIT2

好的,所以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压制之前)。