मेरे पास कई फाइलें हैं जहां मुझे मिलान मूल्यों के साथ एक मैट्रिक्स बनाने की आवश्यकता है

File_1, जो कि प्राथमिक फ़ाइल है, में एक पंक्ति से सीमांकित सभी नंबर टैब शामिल हैं

  Sample_1   23   45   46   67   78   47   98   73   87   45   97   21

ऐसी कई फाइलें हैं जहां यदि कोई संख्या मेल खाती है, तो 1 जोड़ें या फिर ऊपर फ़ाइल में 0 जोड़ें

फ़ाइल_2

Sample_2
23
67
47
235
87
102
97

फ़ाइल_3

Sample_3
67
51
78
98
52
12
21
124

उत्पादन

Sample_1   23   45   46   67   78   47   98   73   87   45   97   21
Sample_2   1    0    0    1    0    1    0    0    1    0    1    0
Sample_3   0    0    0    1    1    0    1    0    0    0    0    1 
1
Empyrean rocks 23 मार्च 2021, 09:23

3 जवाब

सबसे बढ़िया उत्तर

awk बचाव के लिए!

$ awk 'function pr() {for(i=2;i<=n;i++) printf "%s%d", OFS,(h[i] in p)+0; print ""}     
       NR==1  {n=split($0,h); print; next} 
       FNR==1 {if(f) pr(); delete p; printf "%s",$0} {f=1;p[$1]} 
       END    {pr()}' file1 file2 file3 | column -t

Sample_1  23  45  46  67  78  47  98  73  87  45  97  21
Sample_2  1   0   0   1   0   1   0   0   1   0   1   0
Sample_3  0   0   0   1   1   0   1   0   0   0   0   1
2
karakfa 23 मार्च 2021, 16:55

दिए गए इनपुट के साथ, एक के नीचे गॉक का उपयोग करने से आवश्यक ओ/पी उत्पन्न होता है।

इनपुट:

$ cat f1
Sample_1   23   45   46   67   78   47   98   73   87   45   97   21

$ cat f2
Sample_2
23
67
47
235
87
102
97

Sample_3
67
51
78
98
52
12
21
124

स्क्रिप्ट:

$ cat t.sh 
#!/usr/bin/env bash

awk -v OFS="\t" '
            NR==1{                             
                  $1=$1; total = split($0, arr); print; nextfile
            }
            function print_rec( i){
             if(has_old)
               for(i=2; i in arr; i++)
                  printf("%s%s",(arr[i] in farr ? 1 : 0 ) , (i<total ? OFS:RS) )
            }
            /^Sample_*/{
                   print_rec(); delete farr;
                   printf ("%s%s",$1, OFS); next 
            }
            NF{
                   farr[$1]; has_old=1;   
            }
            END{
                print_rec();
            }' f1 f2 

आउटपुट:

$ chmod +x t.sh 
$ ./t.sh 
Sample_1    23  45  46  67  78  47  98  73  87  45  97  21
Sample_2    1   0   0   1   0   1   0   0   1   0   1   0
Sample_3    0   0   0   1   1   0   1   0   0   0   0   1
3
Akshay Hegde 24 मार्च 2021, 06:51

समाधान एल्गोरिथ्म हो सकता है:

  • पहली फ़ाइल पढ़ें और एक हैश में डेटा को एक कुंजी के रूप में नमूना नाम के साथ संग्रहीत करें और सरणी डेटा के रूप में आराम करें
  • रिकॉर्ड विभाजक के रूप में एक खाली लाइन के साथ रिकॉर्ड के रूप में दूसरी फ़ाइल पढ़ें
  • नमूना नाम और डेटा की एक सरणी में रिकॉर्ड विभाजित करें
  • सरणी डेटा इकाई के साथ एक कुंजी के रूप में एक हैश बनाएं और मान असाइन करें 1
  • नमूना_1 . के लिए सरणी में तत्व उपस्थिति के आधार पर डेटा सरणी को 0 या 1 पर रीमैप करें
  • नमूने हैश में परिणाम स्टोर करें
  • कुंजी पर सॉर्ट किए गए नमूने के प्रत्येक तत्व के लिए आउटपुट नमूना नाम और डेटा सरणी
use strict;
use warnings;
use feature 'say';

my $file_1 = 'sample_1.dat';
my $file_2 = 'samples.dat';
my $samples;

open my $fh, '<', $file_1
    or die "Couldn't open $file_1";
my ($name,@genome) = split(' ', <$fh>);
close $fh;

$samples->{$name} = \@genome;

{
    $/ = "\n\n";

    open $fh, '<', $file_2
        or die "Couldn't open $file_2";
        
    while( my $block = <$fh> ) {
        my($name,@genome) = split(' ', $block);
        my %hash;
        $hash{$_} = 1 for @genome;
        @genome = map{ $hash{$_} ? 1 : 0 } @{$samples->{Sample_1}};
        $samples->{$name} = \@genome;
    }

    close $fh;
}

for my $sample ( sort keys %$samples ) {
    say "$sample " . join("\t",@{$samples->{$sample}}) 
}

उत्पादन

Sample_1 23     45      46      67      78      47      98      73      87      45      97      21
Sample_2 1      0       0       1       0       1       0       0       1       0       1       0
Sample_3 0      0       0       1       1       0       1       0       0       0       0       1
2
Polar Bear 23 मार्च 2021, 12:56