我有一个输入文件如下:
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
答案 0 :(得分:8)
使用tr:
cat input_file | tr "\n" " "
答案 1 :(得分:5)
使用粘贴命令:
paste -d ' ' - - - - - < tmp.txt
paste
要好得多,但我无法自拔
删除我之前基于mapfile
的解决方案。
[更新:与mapfile
一起使用时,-n
在版本4.2.35之前读取太多行
#!/bin/bash
file=timing.csv
while true; do
mapfile -t -n 5 arr
(( ${#arr} > 0 )) || break
echo "${arr[*]}"
done < "$file"
exit 0
我们无法执行while mapfile ...; do
因为mapfile
存在状态为0,即使它没有读取任何输入。
答案 2 :(得分:3)
如果您的输入始终包含每行一致的空格数,则可以使用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
我没有注意到使用非常大的文件会带来任何性能提升,但它不需要多个命令。
答案 3 :(得分:3)
在纯粹的bash中,没有外部进程(速度):
while true; do
out=()
for (( i=0; i<5; i++ )); do
read && out+=( "$REPLY" )
done
if (( ${#out[@]} > 0 )); then
printf '%s ' "${out[@]}"
echo
fi
if (( ${#out[@]} < 5 )); then break; fi
done <input-file >output-file
这可以正确处理行数不是5的倍数的文件。
答案 4 :(得分:2)
使用sed,但是这个不会处理最后几行没有添加到5的因子:
sed 'N;N;N;N;s/\n/ /g;' input_file
N
命令读取下一行并将其附加到当前行,保留换行符。此脚本为其读取的每一行读取另外四行,在缓冲区中累积5行的块。对于每个这样的块,它用空格替换所有换行符。
答案 5 :(得分:1)
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
也应该相当快。