我有兩個檔案,
>cat foo.txt
QGP 1044
TGP 634
KGP 616
DGA 504
PGP 481
KGD 465
QGE 456
TGD 393
DGS 367
TGA 366
>cat bar.txt
QGP 748.6421
TGP 564.0048
KGP 568.7543
DGA 193.6391
PGP 405.1929
KGD 248.7047
QGE 287.7652
TGD 246.6278
DGS 143.6255
TGA 210.1166
兩個檔案中的第 1 列相同。我需要像這樣進行數學運算,
(foo.txt$column2 - bar.txt$column2)/sqrt(bar.txt$column2)
并輸出 column1 和數學運算的 column2。我不知道如何使用 awk 遍歷每一行。非常感謝任何幫助!
uj5u.com熱心網友回復:
慣用的技術是:遍歷第一個檔案,并創建一個從 $1 到 $2 的映射。然后,遍歷第二個檔案,并使用當前 $1 的映射
awk '
NR == FNR { # this condition is true for the lines of the first file [1]
foo[$1] = $2
next
}
{
print $1, (foo[$1] - $2) / sqrt($2)
}
' foo.txt bar.txt
輸出
QGP 10.7947
TGP 2.94732
KGP 1.98107
DGA 22.3034
PGP 3.76599
KGD 13.7153
QGE 9.91737
TGD 9.32047
DGS 18.6388
TGA 10.754
[1]:NR == FNR
FNR是當前檔案的記錄號。NR是到目前為止看到的所有檔案的總記錄數。這些值僅對第一個檔案相同。當第一個檔案為空時,這會發生故障。在這種情況下,NR == FNR對于至少有一行的第一個檔案是正確的。更可靠的條件是:
awk '
FILENAME == ARGV[1] {
do stuff for the first file
next
}
{
this action is for each subsequent file
}
' file1 file2 ...
uj5u.com熱心網友回復:
你可以使用join:
$ join foo.txt bar.txt | awk '{print ($2 - $3)/sqrt($3)}'
或(假設檔案已正確排序)使用 awk 讀取備用行:
$ awk '{getline b < "bar.txt"; split(b, a); print ($2 - a[2])/sqrt(a[2])}' foo.txt
uj5u.com熱心網友回復:
perl 解決方案:
paste foo.txt bar.txt | \
perl -F'\t' -lane 'print join "\t", $F[0], ( ($F[1] - $F[3]) / ($F[3])**0.5 );' > out.txt'
Perl 單行器使用這些命令列標志:
-e:告訴 Perl 查找行內代碼,而不是在檔案中。
-n:一次回圈輸入一行,$_默認情況下將其分配給。
-l: 在執行行內代碼之前去除輸入行分隔符("\n"默認情況下在 *NIX 上),并在列印時附加它。:在空格或選項中指定的正則運算式上
-a拆分$_為陣列。: 在 TAB 上拆分,而不是在空格上。該陣列是零索引的。@F-F
-F'/\t/'@F@F
還請參見
perldoc perlrun::如何執行 Perl 解釋器:命令列開關
uj5u.com熱心網友回復:
還有一種寫法:
$ awk '{
if($1 in a) # if index has been met before ie. 2nd file
print $1,(a[$1]-$2)/sqrt($2) # compute and output
else # else 1st file
a[$1]=$2 # hash the value
}' foo bar
一些輸出:
QGP 10.7947
TGP 2.94732
KGP 1.98107
...
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/473787.html
