Shell

每次在其他列上找到數字時,如何添加帶有更改的數字或字元串的列?

  • September 20, 2019

我有一個包含不同列的文件(在此簡化範例中為三個)。這些行包含不同複製的數據(Replicate_A、Replicate_B、Replicate_C)。但是,每個複制的行數不同(例如可以是 3、4、5 行)。我唯一知道的是每個複制都以數字 1 開頭。我想添加一個帶有複製名稱的額外列。關於如何添加該列的任何建議?我可以創建一個額外的文件,其中包含要添加到這個額外列中的名稱列表。任何建議都是有幫助的。

我擁有的文件是一個製表符分隔的文件。

1 x x  
2 x x  
3 x x  
4 x x  
1 x x  
2 x x  
3 x x  
1 x x  
2 x x  
3 x x

我想要的文件

1 x x Replicate_A
2 x x Replicate_A
3 x x Replicate_A
4 x x Replicate_A
1 x x Replicate_B
2 x x Replicate_B
3 x x Replicate_B
1 x x Replicate_C
2 x x Replicate_C
3 x x Replicate_C

如果您可以使用數字而不是字母,您可以在 awk 中非常輕鬆地執行此操作(file具有在您的範例數據上執行的輸出,sed -i 's/ */\t/g'用製表符替換所有連續的空格,因為您說您的數據是製表符分隔的):

$ awk -F"\t" -vOFS="\t" '{if($1==1){num++}{print $0,"Replicate_"num}}' file 
1   x   x       Replicate_1
2   x   x       Replicate_1
3   x   x       Replicate_1
4   x   x       Replicate_1
1   x   x       Replicate_2
2   x   x       Replicate_2
3   x   x       Replicate_2
1   x   x       Replicate_3
2   x   x       Replicate_3
3   x   x   Replicate_3

如果您需要字母,它會更複雜一些,但還不錯:

$ awk '{
       if(NR==FNR){
           a[++n]=$1
       }
       else{
           if($1==1){
               num++
           }
           print $0,"Replicate_"a[num]
       }
      }' <(printf '%s\n' {A..Z}) file
1   x   x    Replicate_A
2   x   x    Replicate_A
3   x   x    Replicate_A
4   x   x    Replicate_A
1   x   x    Replicate_B
2   x   x    Replicate_B
3   x   x    Replicate_B
1   x   x    Replicate_C
2   x   x    Replicate_C
3   x   x Replicate_C

使用 AWK,使用單獨的文件列出要添加的名稱:

#!/usr/bin/awk -f

BEGIN { FS = "\t"; OFS = FS; idx = 0 }
FNR == NR { names[NR] = $0 }
FNR < NR && $1 == 1 { idx++ }
FNR < NR { $(NF + 1) = names[idx]; print }

這將 AWK 設置為使用製表符作為輸入和輸出的欄位分隔符。假定第一個文件包含要添加的名稱;這被讀入names數組。一旦我們移動到第一個之後的文件,我們在檢查第一個欄位是否為 1 並增加數組索引之後,將目前名稱添加到行尾。

沒有單獨的名稱列表:

#!/usr/bin/awk -f

BEGIN { FS = "\t"; OFS = FS; idx = 0 }
$1 == 1 { idx++ }
{ $(NF + 1) = sprintf("Replicate_%c", 64 + idx); print }

在這兩種情況下,都沒有錯誤處理。在第一個變體中,一旦名稱用完,就會使用空字元串。在第二部分中,您將探索 Z 之後的字元集…

引用自:https://unix.stackexchange.com/questions/542780