提取某個字串,搜尋並替換或保留包含提取值的較長字串

提取某個字串,搜尋並替換或保留包含提取值的較長字串

需要編輯的輸入檔如下(可以有更多行):

bundle_id   target_id   length  eff_length  tot_counts  uniq_counts est_counts  eff_counts  ambig_distr_alpha   ambig_distr_beta    fpkm    fpkm_conf_low   fpkm_conf_high  solvable    tpm
1   intron_FBgn0035847:4_FBgn0035847:3  61  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00
2   intron_FBgn0032515:2_FBgn0032515:4  72  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00
3   intron_FBgn0266486:5_FBgn0266486:4  58  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00
4   intron_FBgn0031359:10_FBgn0031359:7 4978    1430.739479 91  0   30.333333   105.539363  1.00E+00    1.00E+00    6.30E+00    1.77E+00    1.08E+01    F   1.42E+01
4   intron_FBgn0031359:10_FBgn0031359:8 4978    1430.739479 91  0   30.333333   105.539363  1.00E+00    1.00E+00    6.30E+00    1.77E+00    1.08E+01    F   1.42E+01
4   intron_FBgn0031359:10_FBgn0031359:9 4978    1430.739479 91  0   30.333333   105.539363  1.00E+00    1.00E+00    6.30E+00    1.77E+00    1.08E+01    F   1.42E+01
536 intron_CR31143:1_CR31143:2  40  0   0   0   0   0   0.00E+00    0.00E+00    0.00E+00    0.00E+00    0.00E+00    F   0.00E+00

對於第二列中的每個 ID內含子_XXXXXXXX:X_XXXXXXXX:X,我想提取之間的字串內含子_和第一個:(在字串之間通常但不總是以 FBgn 開頭)。

然後我有一個如下列表(一列用於FBgn以及我希望將 FBgn 轉換成的相應名稱的另一列):

## FlyBase Gene Mapping Table   
## Generated: Fri Dec 20 12:37:29 2013  
## Using datasource: dbi:Pg:dbname=fb_2014_01_reporting;host=flysql9;port=5432...   
FBgn0035847 mthl7
FBgn0032515 loqs
FBgn0266486 CG45085
FBgn0031359 CG18317

然後我想在列表的第一列中搜尋提取的字串。

如果提取的字串在第二列有對應的值,我想替換整個ID內含子_FBgnXXXXXX:X_FBgnXXXXXX:X與第二列中的對應名稱。

如果提取的字串不存在於第一列中,我想替換整個ID內含子_XXXXXXXX:X_XXXXXXXX:X與提取的字串。

我有一個腳本如下:

ref="gene_map_table_fb_2014_01_short.tsv"
target="HC25_LNv_ZT02_intron_results.txt"
output="temptemp.txt"

declare -A map
while read line
do
if [[ ! -z "$line" ]] && [[ ! "$line" =~ ^#.* ]]
then
key=$(echo "$line" | cut -f 1)
value=$(echo "$line" | cut -f 2)
map[$key]=$value
fi
done < $ref

while read line
do
  key=$(echo "$line" | sed -n 's/.*_\([^\.]*\)\:.*/\1/p' | head -1)
if [ ! -z "$key" ]
then
  echo "$line" | sed 's/intron_[^[:space:]]*/'${map[$key]}'/g' >> $output
else
  echo "$line" | sed 's/intron_[^[:space:]]*/'$key'/g' >> $output
fi
done < $target

一切似乎都運作正常,除了輸出檔案缺少 ID 不以 FBgn 開頭的行。

答案1

你能行的:

cat gene_map_table_fb_2014_01_short.tsv  |sed '1d' |awk {'print $2'} |awk 'BEGIN{FS=":"} {print $2}' |sed s/._//g

首先cat你的文件,然後刪除第一行(有d1的列標題),然後列印所有列,然後4_FBgn0035847用分隔awk 'BEGIN{FS=":"} {print $2}'然後number_用消除sed s/._//g

輸出是:

FBgn0035847
FBgn0032515
FBgn0266486
1FBgn0031359
1FBgn0031359
1FBgn0031359
CR31143

但是,如果您的結束行是多餘的並且您想刪除它,您可以這樣做:

cat gene_map_table_fb_2014_01_short.tsv  |sed '1d' |awk {'print $2'} |awk 'BEGIN{FS=":"} {print $2}' |sed s/._//g |sed '$d'

所以,輸出是:

FBgn0035847
FBgn0032515
FBgn0266486
1FBgn0031359
1FBgn0031359
1FBgn0031359

答案2

使用awk

這將創建製表符分隔的輸出:

$ awk -v OFS="\t" 'NR==FNR{a[$1]=$2;next} FNR==1{print;next} {sub(/intron_/, "", $2); sub(/:.*/,"",$2);if ($2 in a) $2=a[$2];print}' gene_map_table_fb_2014_01_short.tsv HC25_LNv_ZT02_intron_results.txt
bundle_id   target_id   length  eff_length  tot_counts  uniq_counts est_counts  eff_counts  ambig_distr_alpha   ambig_distr_beta    fpkm    fpkm_conf_low   fpkm_conf_high  solvable    tpm
1       mthl7   61      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
2       loqs    72      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
3       CG45085 58      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
536     CR31143 40      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00

解釋:

  • -v OFS="\t"

    這使得輸出字段分隔符號變成一個選項卡。

  • NR==FNR{a[$1]=$2;next}

    a這將根據命令列上的第一個檔案建立一個關聯數組,其中第一列作為鍵,第二列作為值。該next命令指示awk跳過其餘命令並跳到下一行。

    映射檔案包含一些註解行。我們可以輕鬆地加入一個額外的if語句來防止它們被加到陣列中a。然而,由於它們沒有害處,所以我們跳過了這個複雜的問題。

  • FNR==1{print;next}

    這將列印標題行不變。

  • {sub(/intron_/, "", $2); sub(/:.*/,"",$2)

    這會刪除第二個欄位中的多餘內容,只留下我們想要的字串。

  • `如果(a 中的 $2)$2=a[$2]

    如果第二個欄位中的字串作為 array 中的鍵存在a,那麼我們將替換其對應的值。

  • print

    列印修改後的行。

使用bash

在腳本中,替換

if [ ! -z "$key" ]

和:

if [[ "$key" && "${map[$key]}" ]]

此時腳本似乎需要知道的是是否key存在於map。修訂後的測試不僅確保它key非空,而且確保它位於 中map

透過這一更改,我得到輸出:

$ cat temptemp.txt 
bundle_id   target_id   length  eff_length  tot_counts  uniq_counts est_counts  eff_counts  ambig_distr_alpha   ambig_distr_beta    fpkm    fpkm_conf_low   fpkm_conf_high  solvable    tpm
1       mthl7   61      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
2       loqs    72      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
3       CG45085 58      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
4       CG18317 4978    1430.739479     91      0       30.333333       105.539363      1.00E+00        1.00E+00        6.30E+00        1.77E+00        1.08E+01        F       1.42E+01
536     CR31143 40      0       0       0       0       0       0.00E+00        0.00E+00        0.00E+00        0.00E+00        0.00E+00        F       0.00E+00

作為旁白text,如果非空則[ ! -z "$key" ]傳回 true 。key這相當於[ -n "$key" ].由於這是一個常見的測試,因此可以進一步縮短為[ "$key" ]。這可用於簡化bash腳本中的幾行。

相關內容