bash:将五行输入合并到每行输出

bash:将五行输入合并到每行输出,bash,shell,unix,Bash,Shell,Unix,我有一个输入文件,如下所示: MB1 00134141 MB1 12415085 MB1 13253590 MB1 10598105 MB1 01141484 ... ... MB1 10598105 我想把5行合并成一行。 我希望我的bash脚本处理bash脚本以产生如下输出- MB1 00134141 MB1 12415085 MB1 13253590 MB1 10598105 MB1 01141484 ... ... ...

我有一个输入文件,如下所示:

MB1 00134141 
MB1 12415085 
MB1 13253590
MB1 10598105
MB1 01141484
...
...
MB1 10598105
我想把5行合并成一行。 我希望我的bash脚本处理bash脚本以产生如下输出-

MB1 00134141 MB1 12415085 MB1 13253590 MB1 10598105 MB1 01141484
...
...
...                                                 
我写了下面的脚本,它的作品,但它是缓慢的文件大小23051行。 我能写一个更好的代码使它更快吗

#!/bin/bash
file=timing.csv
x=0
while [ $x -lt $(cat $file | wc -l) ]
do
   line=`head -n $x $file | tail -n 1`
   echo -n $line " "
   let "remainder = $x % 5"
   if [ "$remainder" -eq 0 ] 
   then
        echo ""
   fi
   let x=x+1
done
exit 0
我试图执行以下命令,但它弄乱了一些数字

cat timing_deleted.csv | pr -at5

使用sed,但这一行不会处理最后几行不增加系数5的行:

 sed 'N;N;N;N;s/\n/ /g;' input_file

N
命令读取下一行并将其附加到当前行,保留换行符。这个脚本为它读取的每一行额外读取四行,在缓冲区中累积5行的块。对于每个这样的块,它用一个空格替换所有的换行符

如果输入的每行空格数始终一致,则可以使用
xargs

cat timing_deleted.csv | xargs -n 10
这将从
cat timing_deleted.csv
中获取输入,并将输入合并到10个(
-n 10
)空白字符上。每列中的空格(如
MB1 00134141
)计为空白字符,以及每行末尾的换行符。因此,对于5行,您需要使用10行

编辑
正如Charles所评论的,您可以跳过
cat
的使用,直接将数据推入
xargs
,方法是:

xargs -n 10 < timing_deleted.csv
xargs-n 10

我没有注意到使用非常大的文件会提高性能,但它不需要多个命令。

在纯bash中,没有外部进程(为了速度):

为true时;做
out=()
对于((i=0;i0));然后
printf'%s'${out[@]}
回声
fi
如果(${out[@]}<5));然后打破;fi
完成输出文件
这将正确处理行数不是5的倍数的文件。

使用粘贴命令:

 paste -d ' ' - - - - - < tmp.txt

当mapfile…,我们不能做
。。。;执行
,因为即使在未读取任何输入的情况下,
映射文件
也以状态0存在。

awk脚本可以执行此操作。我想也是一个很好的替代品。我不太了解塞德,给你

NF{ 
    if(i>=5){
        line = line "\n";
        i=0;
    }else{
        line = line " " $0;
        i++;
    }
}

END{
    print line;
}
称之为merge.awk。以下是您的发票开具方式:

    awk -f merge.awk filetomerge.txt
cat filetomerge.txt|awk-f merge.awk

也应该相当快。

使用tr:

cat input_file | tr "\n" " "

只需在循环之前保存
cat$file | wc-l
的值,而不是每次通过循环调用它,就可以加快速度。我想知道为什么
pr-at5 timing_deleted.csv
不起作用。。。当我尝试时,它运行得非常好,而且非常快。。这个文件有dos风格的行尾还是什么的?这个可以工作,但我可以看到它比SED慢。可能是因为它运行两个进程并通过管道输出。谢谢你的解决方案@RajTendulkar是的,这是一个有价值的观点;然而,我并没有抨击另一个解决方案——这是一个很好的解决方案,但如果最后几行加起来不是偶数5(当然,除非你也传入
-x
选项)。没有理由在这里使用
cat
xargs-n10是的,这很好!仅针对每个数字长度的变化,输出被视为具有不规则的空格或制表符。但它工作正常!:)谢谢浆糊应该很好用;我将修复基于mapfile的解决方案中的一个小错误。很好——我很不好意思自己没有想到使用粘贴。或者如果您更喜欢模糊的awk:
awk ORS=NR%5\?FS:RS
:)我这样做是因为在终端中只打印一次更快,但不确定它是否有意义。有些awk机制对我来说还不清楚。。。很高兴知道。是的,缓冲整个输入没有什么好处。此外,如果输入大于可用内存,awk将失败。下面的另一个答案是更好的,
cat input_file | tr“\n”“”
@charneykaye,OP表示他们希望合并五行的批次,而不是所有行。阅读这个问题。查尔斯,这是一个很好的观点——在我看来,问题标题“bash脚本在一行上输出多行”应该被编辑以反映这一点。否则,下面的答案对那些(像我一样)问这个简单问题的人来说是最有用的。cat的无用用法:这最好写成
tr'\n''。此外,这也不能满足问题的要求:它将所有输入合并到一行,而不是将五行输入合并到每行输出中。这不符合问题要求
    awk -f merge.awk filetomerge.txt
cat input_file | tr "\n" " "