Awk 将文本文件按列与不同行数组合
我希望有人能帮助我。 希望我能用带有一些选项的“粘贴”或“awk”命令(或其他简单命令)完成这项任务 我有许多不同行数的文件。 我想按列方式合并这些文件,但没有像我所希望的那样成功。问题如下Awk 将文本文件按列与不同行数组合,awk,paste,Awk,Paste,我希望有人能帮助我。 希望我能用带有一些选项的“粘贴”或“awk”命令(或其他简单命令)完成这项任务 我有许多不同行数的文件。 我想按列方式合并这些文件,但没有像我所希望的那样成功。问题如下 F1.txt 1 549 15981 2 835 19591 3 322 3896 4 298 3778 F2.txt 1 549 15981 2 835 19591 3 322 3896 4 298 3778 5 16 202 我想要的是 1 549
F1.txt
1 549 15981
2 835 19591
3 322 3896
4 298 3778
F2.txt
1 549 15981
2 835 19591
3 322 3896
4 298 3778
5 16 202
我想要的是
1 549 15981 1 549 15981
2 835 19591 2 835 19591
3 322 3896 3 322 3896
4 298 3778 4 298 3778
5 16 202
但我用命令“粘贴F1.txt F2.txt | column-s$'\t'-tn”得到的结果是
如您所见,由于F1没有第五行,所以F2的第五行向右移动。这不是我想要的。希望有人能帮助解决这个问题 输入
输出
使用awk
,但它将使用数组
,所以如果文件太大,可能会遇到内存问题
$ awk -v OFS="\t" 'FNR==NR{a[FNR]=$0;m=m>length?m:length;next}{print (FNR in a)?a[FNR]:sprintf("%*s",length,""),$0}' f1 f2
1 549 15981 1 549 15981
2 835 19591 2 835 19591
3 322 3896 3 322 3896
4 298 3778 4 298 3778
5 16 202
解释
这里有一种使用pr
尝试使用sed或其他实用程序来抑制多余的选项卡,如下所示
$ pr -mt f1 f2 | sed -E 's/[\t]{3}/\t/g'
1 549 15981 1 549 15981
2 835 19591 2 835 19591
3 322 3896 3 322 3896
4 298 3778 4 298 3778
5 16 202
您可以使用以下代码:
paste F* | awk '($0~/^\t/){$0="\t" $0}{print}'
您可以简化粘贴f1 f2 | awk'/^\t/{$0=“\t”$0}1'无法复制,工作正常(需要对齐)您的输入文件需要以制表符分隔,而不是空格分隔。Ed,非常感谢。你解决了我的问题。
awk -v OFS="\t" '
FNR==NR{
a[FNR]=$0; # save each record of file f1 in array a
m=m>length?m:length; # find max length of line/row from file f1
next # go to next line
}
# read file f2
{
# if value exists in array a for row index then
# print array element, else sprintf with the length of max length line
# and current line/row/record of file f2
print (FNR in a)?a[FNR]:sprintf("%*s",length,""),$0
}' f1 f2
$ pr -mt f1 f2
1 549 15981 1 549 15981
2 835 19591 2 835 19591
3 322 3896 3 322 3896
4 298 3778 4 298 3778
5 16 202
$ pr -mt f1 f2 | sed -E 's/[\t]{3}/\t/g'
1 549 15981 1 549 15981
2 835 19591 2 835 19591
3 322 3896 3 322 3896
4 298 3778 4 298 3778
5 16 202
paste F* | awk '($0~/^\t/){$0="\t" $0}{print}'