Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 匹配模式后,将右侧的列附加到awk文件_Perl_Bash_Unix_Scripting_Awk - Fatal编程技术网

Perl 匹配模式后,将右侧的列附加到awk文件

Perl 匹配模式后,将右侧的列附加到awk文件,perl,bash,unix,scripting,awk,Perl,Bash,Unix,Scripting,Awk,我有两个文件,其中一个只是列向量,例如: 1x23 1y21 1z21 1z25 另一种是矩阵的形式 1x23 1x24 1y21 1y22 1y25 1z22 class 2000 3000 4000 5000 6000 7000 Yes 1500 1200 1100 1510 1410 1117 No 首先,我想找出第一个文件中的哪些行与第二个文件中的第一行相匹配。其次,我想复制第二个文件中与第一个文件中的列相匹配的列,并将它们附加到第二个文件中。因此,由于1x23,1x21匹配,我想复

我有两个文件,其中一个只是列向量,例如:

1x23
1y21
1z21
1z25
另一种是矩阵的形式

1x23 1x24 1y21 1y22 1y25 1z22 class
2000 3000 4000 5000 6000 7000 Yes
1500 1200 1100 1510 1410 1117 No
首先,我想找出第一个文件中的哪些行与第二个文件中的第一行相匹配。其次,我想复制第二个文件中与第一个文件中的列相匹配的列,并将它们附加到第二个文件中。因此,由于1x23,1x21匹配,我想复制第二列中的这两列,并将其追加到类变量之前

我希望我的结果是正确的

1x23 1x24 1y21 1y22 1y25 1z22 1x23 1y21 class
2000 3000 4000 5000 6000 7000 2000 4000 Yes
1500 1200 1100 1510 1410 1117 1500 1100 No

我使用perl为3的循环编写代码,但由于数据非常大,它崩溃了。我认为应该有有效的方法来做到这一点

不确定Perl代码为何会崩溃。我建议在恒定内存中运行以下算法(在Perl中实现时可能比在AWK中更可读):

  • 读取第一个文件并生成列名列表
  • 读取数据文件的第1行(带实际标题)
  • 将两个列表相交以生成列索引列表
  • 读取数据文件的一行并按列拆分
  • 通过使用步骤3中构建的“必需”列索引列表对列值进行索引,创建一个新的列值数组。输出它
  • 重复最后2个步骤

不确定Perl代码为何会崩溃。我建议在恒定内存中运行以下算法(在Perl中实现时可能比在AWK中更可读):

  • 读取第一个文件并生成列名列表
  • 读取数据文件的第1行(带实际标题)
  • 将两个列表相交以生成列索引列表
  • 读取数据文件的一行并按列拆分
  • 通过使用步骤3中构建的“必需”列索引列表对列值进行索引,创建一个新的列值数组。输出它
  • 重复最后2个步骤
    • 你可以试试

      awk -f app.awk file1.txt file2.txt
      
      其中,
      file1.txt
      是您的第一个文件,
      file2.txt
      是第二个文件,
      app.awk

      NR==FNR {
          key[$0]++
          next
      }
      {
          for (i=1; i<=NF; i++)
              C[FNR,i]=$i
      }
      
      END {
          for (i=1; i<=NF; i++) 
              if (C[1,i] in key) 
                  k[++j]=i                
          nc=j
          for (j=1; j<=FNR; j++) {
              for (i=1; i<NF; i++) 
                 printf "%s%s",C[j,i],OFS     
              for (i=1; i<=nc; i++) 
                 printf "%s%s",C[j,k[i]],OFS      
              printf "%s%s",C[j,NF],RS
          }
      }
      
      NR==FNR{
      钥匙[$0]++
      下一个
      }
      {
      对于(i=1;i您可以尝试

      awk -f app.awk file1.txt file2.txt
      
      其中,
      file1.txt
      是您的第一个文件,
      file2.txt
      是第二个文件,
      app.awk

      NR==FNR {
          key[$0]++
          next
      }
      {
          for (i=1; i<=NF; i++)
              C[FNR,i]=$i
      }
      
      END {
          for (i=1; i<=NF; i++) 
              if (C[1,i] in key) 
                  k[++j]=i                
          nc=j
          for (j=1; j<=FNR; j++) {
              for (i=1; i<NF; i++) 
                 printf "%s%s",C[j,i],OFS     
              for (i=1; i<=nc; i++) 
                 printf "%s%s",C[j,k[i]],OFS      
              printf "%s%s",C[j,NF],RS
          }
      }
      
      NR==FNR{
      钥匙[$0]++
      下一个
      }
      {
      
      对于(i=1;i,这里有一个冗长但不明确的方法

      use strict;
      use warnings;
      
      open(my $data, '<', 'data.txt');
      
      # read first row from the data file
      my $line = <$data>;
      chomp $line;
      
      # create a list of columns
      my @cols = split / /, $line;
      
      # create hash with column indexes
      my %colindex;
      my $i = 0;
      foreach my $colname (@cols) {
              $colindex{$colname} = $i++;
      }
      
      # Save last column ('class')
      my $lastcol = pop @cols;
      
      # get input (column names)
      open(my $input, '<', 'input.txt');
      my @colnames = <$input>;
      close $input;
      
      # append column names to array if there is a match
      foreach (@colnames) {
              chomp;
              if (exists $colindex{$_}) {
                      push @cols, $_;
              }
      }
      
      # Restore the last column
      push @cols, $lastcol;
      
      # Now process your data
      open(my $out, '>', 'output.txt');
      
      # write the header column
      print $out join(" ", @cols), "\n";
      
      while ($line = <$data>) {
              chomp $line;
              my @l = split / /, $line;
              foreach my $colname (@cols) {
                      print $out $l[$colindex{$colname}], " ";
              }
              print $out "\n";
      }
      
      close $out;
      close $data;
      
      使用严格;
      使用警告;
      打开(my$data,,'output.txt');
      #写入标题列
      打印$out join(“,@cols),“\n”;
      而($line=){
      chomp$行;
      我的@l=拆分/,$line;
      foreach我的$colname(@cols){
      打印$out$l[$colindex{$colname}],“”;
      }
      打印$out“\n”;
      }
      收尾美元;
      关闭$数据;
      
      这里有一个冗长而清晰的方法

      use strict;
      use warnings;
      
      open(my $data, '<', 'data.txt');
      
      # read first row from the data file
      my $line = <$data>;
      chomp $line;
      
      # create a list of columns
      my @cols = split / /, $line;
      
      # create hash with column indexes
      my %colindex;
      my $i = 0;
      foreach my $colname (@cols) {
              $colindex{$colname} = $i++;
      }
      
      # Save last column ('class')
      my $lastcol = pop @cols;
      
      # get input (column names)
      open(my $input, '<', 'input.txt');
      my @colnames = <$input>;
      close $input;
      
      # append column names to array if there is a match
      foreach (@colnames) {
              chomp;
              if (exists $colindex{$_}) {
                      push @cols, $_;
              }
      }
      
      # Restore the last column
      push @cols, $lastcol;
      
      # Now process your data
      open(my $out, '>', 'output.txt');
      
      # write the header column
      print $out join(" ", @cols), "\n";
      
      while ($line = <$data>) {
              chomp $line;
              my @l = split / /, $line;
              foreach my $colname (@cols) {
                      print $out $l[$colindex{$colname}], " ";
              }
              print $out "\n";
      }
      
      close $out;
      close $data;
      
      使用严格;
      使用警告;
      打开(my$data,,'output.txt');
      #写入标题列
      打印$out join(“,@cols),“\n”;
      而($line=){
      chomp$行;
      我的@l=拆分/,$line;
      foreach我的$colname(@cols){
      打印$out$l[$colindex{$colname}],“”;
      }
      打印$out“\n”;
      }
      收尾美元;
      关闭$数据;
      
      试试这一行:

      awk 'NR==FNR{a[$0]=1;next}FNR==1{for(i=1;i<=NF;i++)if(a[$i])k[i]}{for(x in k)$NF= sprintf("%s ",$x) $NF}7' f1 f2 
      
      试试这一行:

      awk 'NR==FNR{a[$0]=1;next}FNR==1{for(i=1;i<=NF;i++)if(a[$i])k[i]}{for(x in k)$NF= sprintf("%s ",$x) $NF}7' f1 f2 
      
      还有一个选择:

      use strict;
      use warnings;
      
      my ( $matrix, @cols ) = pop;
      my %headings = map { chomp; $_ => 1 } <>;
      
      push @ARGV, $matrix;
      while (<>) {
          my @array = split;
          @cols = grep $headings{ $array[$_] }, 0 .. $#array if $. == 1;
          splice @array, -1, 0, @array[@cols];
          print "@array\n";
      }
      
      使用向量文件中的条目创建散列。矩阵文件第一行上所有实体的列位置都保存在
      @col
      中。将
      拆分
      矩阵行中匹配的列条目插入到
      拆分
      矩阵行的最后一个元素之前。最后,新行是
      print
      ed

      希望这有帮助!

      这里有另一个选项:

      use strict;
      use warnings;
      
      my ( $matrix, @cols ) = pop;
      my %headings = map { chomp; $_ => 1 } <>;
      
      push @ARGV, $matrix;
      while (<>) {
          my @array = split;
          @cols = grep $headings{ $array[$_] }, 0 .. $#array if $. == 1;
          splice @array, -1, 0, @array[@cols];
          print "@array\n";
      }
      
      使用向量文件中的条目创建散列。矩阵文件第一行上所有实体的列位置都保存在
      @col
      中。将
      拆分
      矩阵行中匹配的列条目插入到
      拆分
      矩阵行的最后一个元素之前。最后,新行是
      print
      ed

      希望这有帮助