问题
I have two files with N number of columns
File1:
A 1 2 3 ....... Na1
B 2 3 4 ....... Nb1
File2:
A 2 2 4 ....... Na2
B 1 3 4 ....... Nb2
i want a output where 1st column value from File1 will be subtracted from 1st column of File2, and this way till column N as shown below:
A -1 0 -1 ........ (Na1-Na2)
B 1 0 0 ........ (Nb1-Nb2)
How to do this is AWK, or Perl scripting in Linux environment?
回答1:
Something like this:
use strict;
use warnings;
my (@fh, @v);
for (@ARGV) {
open (my $handle, "<", $_) or die ("$!: $_");
push @fh, $handle;
}
while (@v = map { [split ' ', <$_> ] } @fh and defined shift @{$v[0]}) {
print join(" ", (shift @{$v[1]}, map { $_ - shift(@{$v[1]}) } @{$v[0]})), "\n";
}
close $_ for (@fh);
To run:
perl script.pl input1 input2
回答2:
This has already been answered, but I will add a one-liner. It uses paste
, to concatenate the files, and awk
to subtract:
paste file{1,2} | awk '{for (i=1;i<=NF/2;i++) printf "%s ", ($i==$i+0)?$i-$(i+NF/2):$i; print ""}'
Validation:
$ cat file1
A 1 2 3 4 5
B 2 3 4 5 6
$ cat file2
A 2 2 4 10 12
B 1 3 4 3 5
$ paste file{1,2} | awk '{for (i=1;i<=NF/2;i++) printf "%s ", ($i==$i+0)?$i-$(i+NF/2):$i; print ""}'
A -1 0 -1 -6 -7
B 1 0 0 2 1
It requires both files to have the same number of columns. Non-numeric columns should be at the same position. It prints the value in the first file if non-numeric, otherwise prints the difference.
回答3:
Try:
awk '{split($0,S); getline<f; for(i=2; i<=NF; i++) $i-=S[i]}1' OFS='\t' f=file1 file2
回答4:
Here's one way using GNU awk
. Run like:
awk -f script.awk File2 File1 | rev | column -t | rev
Contents of script.awk
:
FNR==NR {
for(i=2;i<=NF;i++) {
a[$1][i]=$i
}
next
}
{
for(j=2;j<=NF;j++) {
$j-=a[$1][j]
}
}1
Alternatively, here's the one-liner:
awk 'FNR==NR { for(i=2;i<=NF;i++) a[$1][i]=$i; next } { for(j=2;j<=NF;j++) $j-=a[$1][j] }1' File2 File1 | rev | column -t | rev
Results:
A -1 0 -1
B 1 0 0
回答5:
awk 'FNR==NR{for(i=2;i<=NF;i++)a[FNR"-"i]=$i;next}{printf "\n"$1" ";for(i=2;i<=NF;i++){printf $i-a[FNR"-"i]" "}}' file1 file2
> cat file1
A 1 2 3
B 2 3 4
> cat file2
A 2 2 4
B 1 3 4
> awk 'FNR==NR{for(i=2;i<=NF;i++)a[FNR"-"i]=$i;next}{printf "\n"$1" ";for(i=2;i<=NF;i++){printf $i-a[FNR"-"i]" "}}' file1 file2
A 1 0 1
B -1 0 0
>
Alternatively put this in a file
#!/usr/bin/awk
FNR==NR{
for(i=2;i<=NF;i++)
a[FNR"-"i]=$i;next
}
{
printf "\n"$1" ";
for(i=2;i<=NF;i++)
{
printf $i-a[FNR"-"i]" "
}
}
and execute as:
awk -f file.awk file1 file2
回答6:
Something like this perhaps? I'm afraid I can't test this code as I have no PC to hand at present.
This program expects the names of the two files as parameters on the command line, and outputs the results to STDOUT
.
use strict;
use warnings;
use autodie;
my @fh;
for my $filename (@ARGV) {
open my $fh, '<', $filename;
push @fh, $fh;
}
until (grep eof $_, @fh) {
my @records;
for my $fh (@fh) {
my $line = <$fh>;
chomp $line;
push @records, [ split ' ', $line ];
}
$records[0][$_] -= $records[1][$_] for 1 .. $#{$records[0]};
print "@{$records[0]}\n";
}
来源:https://stackoverflow.com/questions/15049478/subtructing-n-number-of-columns-from-two-files-with-awk