将文本文件列与不同行数组合

时间:2017-09-01 04:50:57

标签: awk paste

我希望有人可以帮助我。 希望我可以使用“paste”或“awk”命令完成此任务,其中包含一些选项(或其他简单命令)。

我有很多行数不同的文件。 我希望将这些文件按列顺序组合,但不能像我喜欢的那样成功。问题如下。

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

outfile我想要的是

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 |列-s $'\ t'-tn”是

EitherT

如您所见,由于F1剂量没有第五行,因此F2的第五行向右移动。这不是我想要的。希望有人可以帮助解决这个问题。

2 个答案:

答案 0 :(得分:0)

<强> 输入

$ cat f1
1   549 15981
2   835 19591
3   322 3896
4   298 3778

$ cat f2
1   549 15981
2   835 19591
3   322 3896
4   298 3778
5   16  202

<强> 输出

使用 awk ,但它会使用array,因此如果您的文件太大,可能会遇到内存问题

$ 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

<强> 解释

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

的一种方法
$ 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

尝试使用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

答案 1 :(得分:0)

您可以使用以下代码:

paste F* | awk '($0~/^\t/){$0="\t" $0}{print}'