【问题标题】:How do I concatenate 2 files follow a some pattern?如何按照某种模式连接 2 个文件?
【发布时间】:2015-09-28 14:42:50
【问题描述】:

我想要做的只是连接 2 个文件,如下例所示:

file 1        file 2
C1            O1             
C3            O3
..            O5
              O7
              O9
              O11
              O13
              O15
              O17
              O19
              ..

想要的输出文件是:

file 3
C1
O1
O9
O17
C3
O3
O11
O19
..
..

所以,模式是:首先是 C1 和 O1,然后是文件 2 中的 3 行(所以,打印 O9);然后在文件 2 中再输出 3 行(因此,打印 O17)。然后打印 C3 和 O3,文件 2 中输出 3 行(O10),输出 3 行(O18);然后是 C5 ...等

我尝试用cat | paste - - - ... 做点什么,但没有成功:(

有什么建议吗?

在此先感谢

编辑

我忘了告诉你它们是大文件。 :)

这是我的输入文件

cat file 1
C             18     -2.182951850        -0.000000000        -6.517815410
C             20     -4.127401075         0.000000000        -0.446529291
C             22     -3.314258919        -2.494999886       -15.624910016
C             24     -6.071850300         0.000000000         5.624757806
C             26     -2.023950100         0.000000000         5.624757806
C             28     -4.286402584        -0.000000000       -12.589102506
C             30     -6.230851809        -0.000000000        -6.517815410
C             32     -0.079500634         0.000000000        -0.446529291

cat file 2
O             34     -1.393125174        -0.640765928        -5.738276269
O             36     -3.337574640        -0.640765928         0.333010828
O             38     -2.524270589         1.854234106       -14.845370570
O             40     -5.282024106        -0.640765928         6.404297925
O             42     -2.182951850         1.281531856        -6.517815410
O             44     -4.127401075         1.281531856        -0.446529291
O             46     -3.314258919        -1.213468178       -15.624910016
O             48     -6.071850300         1.281531856         5.624757806
O             50     -2.972778044        -0.640765928        -7.297355528
O             52     -4.917227269        -0.640765928        -1.226068432
O             54     -4.104085113         1.854234106       -16.404449463
O             56     -6.861676614        -0.640765928         4.845217687
O             58     -2.813776294         0.640765779         4.845217687
O             60     -5.076228778         0.640765779       -13.368642136
O             62     -7.020678123         0.640765779        -7.297355528
O             64     -0.869326828         0.640765779        -1.226068432
O             66     -2.023950100        -1.281531708         5.624757806
O             68     -4.286402584        -1.281531708       -12.589102506
O             70     -6.230851809        -1.281531708        -6.517815410
O             72     -0.079500634        -1.281531708        -0.446529291
O             74     -1.234123906         0.640765779         6.404297925
O             76     -3.496576390         0.640765779       -11.809563365
O             78     -5.441025615         0.640765779        -5.738276269
O             80      0.710325077         0.640765779         0.333010828

C18 后面必须跟 O34、O42 和 O50。然后是 C20,然后是 O36、O44 和 O52,依此类推:

cat file 3
C             18     -2.182951850        -0.000000000        -6.517815410 
O             34     -1.393125174        -0.640765928        -5.738276269
O             42     -2.182951850         1.281531856        -6.517815410
O             50     -2.972778044        -0.640765928        -7.297355528
C             20     -4.127401075         0.000000000        -0.446529291
O             36     -3.337574640        -0.640765928         0.333010828
O             44     -4.127401075         1.281531856        -0.446529291
O             52     -4.917227269        -0.640765928        -1.226068432
..             ..      ............        .............       .........

Tom 代码生成的输出是这样的:

Tom output
C             18     -2.182951850        -0.000000000        -6.517815410
O             34     -1.393125174        -0.640765928        -5.738276269
O             42     -2.182951850         1.281531856        -6.517815410
O             50     -2.972778044        -0.640765928        -7.297355528
O             58     -2.813776294         0.640765779         4.845217687
O             66     -2.023950100        -1.281531708         5.624757806
O             74     -1.234123906         0.640765779         6.404297925
C             20     -4.127401075         0.000000000        -0.446529291
O             36     -3.337574640        -0.640765928         0.333010828
O             44     -4.127401075         1.281531856        -0.446529291
O             52     -4.917227269        -0.640765928        -1.226068432
O             60     -5.076228778         0.640765779       -13.368642136
O             68     -4.286402584        -1.281531708       -12.589102506
O             76     -3.496576390         0.640765779       -11.809563365
C             22     -3.314258919        -2.494999886       -15.624910016
O             38     -2.524270589         1.854234106       -14.845370570
O             46     -3.314258919        -1.213468178       -15.624910016
O             54     -4.104085113         1.854234106       -16.404449463
O             62     -7.020678123         0.640765779        -7.297355528
O             70     -6.230851809        -1.281531708        -6.517815410
O             78     -5.441025615         0.640765779        -5.738276269
and     so   on

有什么建议吗?

谢谢

【问题讨论】:

  • 我们在这里谈论多大?兆字节?千兆字节?例如,超出你的记忆力?
  • Also ... C1 匹配 O1,C3 匹配 O3... 大概 C3 之后的行匹配 O5,之后的行匹配 O7。之后会发生什么?还是只有四次迭代?
  • @ghoti 它们很大,但没有千兆字节那么大。该序列已在问题的编辑部分显示在上面...
  • 您的编辑没有回答初始模式用尽后会发生什么的问题。您描述的模式仅支持四次迭代,因为对于从 C26 开始的集合,您已经用完了 O42。还是我们重复 O42 以使其成为新系列的一部分?还是我们向前跳,让 C26 跟在 O58 后面?
  • @ghoti 抱歉,迭代重复到所有“C”行与其相关的“O”行相结合。我不知道具体有多少行“C”,因为这取决于我的初始设置。如果算上,模式是:第一个 C 行与第一个 O 行,然后是 O 第 4 行,然后是第 9 个 O 行(中间有 3 行);接下来的第 2 个 C 行与第 2 个 O 行一起,然后是第 5 个 O 行,然后是第 10 行……依此类推。我希望现在很清楚。非常感谢

标签: bash shell paste cat


【解决方案1】:

我建议使用 awk 来执行此操作:

# first file
NR == FNR { 
    a[NR] = $0  # save each line into array
    ++len
    next        # skip further blocks
}

{ b[FNR] = $0 } # save each line from 2nd file into array

END {
    # loop through and print
    for (i = 1; i <= len; ++i) {
        print a[i]
        for (j = i; j <= FNR; j += 4) print b[j]
    }
}

脚本可以像awk -f script.awk file1 file2一样运行。

【讨论】:

  • 好的,这是一个很好的解决方案,但我已经在使用脚本,所以我可以在那里实现代码。非常感谢
  • 如果你的意思是一个 shell 脚本并且你想内联运行 awk 脚本,你可以把这个脚本用引号括起来,然后像 awk 'script' file1 file2 这样调用它。
  • 我在我的 shell 脚本中做了awk -f $SCRIPTDIR/script.awk infile1 infile2 &gt; outfile
  • 看起来不错。一些一般性建议,引用你的变量,不要使用大写变量名(因为它们可能与 shell 内部冲突):awk -f "$script_dir/concat.awk" ...
【解决方案2】:

您所描述的(通过 cmets 中的确认)是一种模式

  • 由 C 行组成
  • 对一组九个 O 线进行采样,从与 C 线相同偏移量的一个开始。

为了处理这个问题,我会使用带有 9 行“滑动窗口”的 awk 作为缓冲区。

而不是使用汤姆的解决方案,将 awk 依次指向两个文件并将一个文件读入数组,我建议同时从两个文件中读取,这样你就不会占用太多内存来保存数组。

这就是我的意思,作为一个单行:

awk '{a[NR]=$0;delete a[NR-10];} NR>9{getline Cline < "fileC";print Cline;print a[NR-9]; print a[NR-5]; print a[NR-1];}' fileO

为了便于阅读(和 cmets)而拆分出来,如下所示:

awk '
  {
    a[NR]=$0;        # Store our current "O" line in an array
    delete a[NR-10]; # Clean the array as we step through the file
  }

  NR>9 {
    getline Cline < "fileC";  # Get the next "C" line...
    print Cline;              # ... and print it
    print a[NR-9];            # \ 
    print a[NR-5];            #  > Print the three "O" lines for this 
    print a[NR-1];            # /
  }
' fileO

请注意,您的“O”行数正确,因为如果最后一组“O”行不完整,则不会打印。

我的示例数据输出如下所示:

C             18     -2.182951850        -0.000000000        -6.517815410
O             34     -1.393125174        -0.640765928        -5.738276269
O             42     -2.182951850         1.281531856        -6.517815410
O             50     -2.972778044        -0.640765928        -7.297355528
C             20     -4.127401075         0.000000000        -0.446529291
O             36     -3.337574640        -0.640765928         0.333010828
O             44     -4.127401075         1.281531856        -0.446529291
O             52     -4.917227269        -0.640765928        -1.226068432
C             22     -3.314258919        -2.494999886       -15.624910016
O             38     -2.524270589         1.854234106       -14.845370570
O             46     -3.314258919        -1.213468178       -15.624910016
O             54     -4.104085113         1.854234106       -16.404449463
C             24     -6.071850300         0.000000000         5.624757806
O             40     -5.282024106        -0.640765928         6.404297925
O             48     -6.071850300         1.281531856         5.624757806
O             56     -6.861676614        -0.640765928         4.845217687
C             26     -2.023950100         0.000000000         5.624757806
O             42     -2.182951850         1.281531856        -6.517815410
O             50     -2.972778044        -0.640765928        -7.297355528
O             58     -2.813776294         0.640765779         4.845217687
C             28     -4.286402584        -0.000000000       -12.589102506
O             44     -4.127401075         1.281531856        -0.446529291
O             52     -4.917227269        -0.640765928        -1.226068432
O             60     -5.076228778         0.640765779       -13.368642136
C             30     -6.230851809        -0.000000000        -6.517815410
O             46     -3.314258919        -1.213468178       -15.624910016
O             54     -4.104085113         1.854234106       -16.404449463
O             62     -7.020678123         0.640765779        -7.297355528
C             32     -0.079500634         0.000000000        -0.446529291
O             48     -6.071850300         1.281531856         5.624757806
O             56     -6.861676614        -0.640765928         4.845217687
O             64     -0.869326828         0.640765779        -1.226068432
C             32     -0.079500634         0.000000000        -0.446529291
O             50     -2.972778044        -0.640765928        -7.297355528
O             58     -2.813776294         0.640765779         4.845217687
O             66     -2.023950100        -1.281531708         5.624757806
C             32     -0.079500634         0.000000000        -0.446529291
O             52     -4.917227269        -0.640765928        -1.226068432
O             60     -5.076228778         0.640765779       -13.368642136
O             68     -4.286402584        -1.281531708       -12.589102506
C             32     -0.079500634         0.000000000        -0.446529291
O             54     -4.104085113         1.854234106       -16.404449463
O             62     -7.020678123         0.640765779        -7.297355528
O             70     -6.230851809        -1.281531708        -6.517815410
C             32     -0.079500634         0.000000000        -0.446529291
O             56     -6.861676614        -0.640765928         4.845217687
O             64     -0.869326828         0.640765779        -1.226068432
O             72     -0.079500634        -1.281531708        -0.446529291
C             32     -0.079500634         0.000000000        -0.446529291
O             58     -2.813776294         0.640765779         4.845217687
O             66     -2.023950100        -1.281531708         5.624757806
O             74     -1.234123906         0.640765779         6.404297925
C             32     -0.079500634         0.000000000        -0.446529291
O             60     -5.076228778         0.640765779       -13.368642136
O             68     -4.286402584        -1.281531708       -12.589102506
O             76     -3.496576390         0.640765779       -11.809563365
C             32     -0.079500634         0.000000000        -0.446529291
O             62     -7.020678123         0.640765779        -7.297355528
O             70     -6.230851809        -1.281531708        -6.517815410
O             78     -5.441025615         0.640765779        -5.738276269

这是你的意思吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-01
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多