Try   HackMD

【新】用 bash 寫個由學名找物種資訊小功能

tags: ubuntu 學習筆記 bash

因為 臺灣物種名錄 網站搬家 + 大改版,原本的物種名錄資料格式也有很大的變動,例如名錄檔案分為「學名」與「物種」兩個檔案,前者記錄了更多的資訊如種下階層(subsp., var., fo.)、原始發表文獻、地位等等。對於整理調查資料來說,應該使用物種名錄檔案即可;但因為學名名錄檔才有紀錄是否為接受名(usage_status),所以我們也只好使用這個檔案來製作本機端的資料庫。如果新版網站延續之前 taibnet 的慣例,那名錄資料會每月更新一次,可以定期下載來更新本地端的比對用物種資料庫。

首先下載檔案:

wget https://taicol.tw/static/upload/TaiCOL_name_20230818.zip
unzip TaiCOL_name_20230818.zip

查看每一行的名稱,共有 49 行,可以使用 awk 指令查看:

awk -F, 'NR==1 {for (i=1; i<=NF; i++) {printf("$%d %s\n", i, $i)}}' TaiCOL_name_20230818.csv
$1 name_id
$2 nomenclature_name
$3 rank
$4 simple_name
$5 name_author
$6 formatted_name
$7 latin_genus
$8 latin_s1
$9 s2_rank
$10 latin_s2
$11 s3_rank
$12 latin_s3
$13 original_name_id
$14 is_hybrid
$15 hybrid_parent
$16 protologue
$17 type_name_id
$18 namecode
$19 created_at
$20 updated_at
$21 usage_status
$22 taxon_id
$23 common_name_c
$24 alternative_name_c
$25 is_in_taiwan
$26 is_endemic
$27 alien_type
$28 is_fossil
$29 is_terrestrial
$30 is_freshwater
$31 is_brackish
$32 is_marine
$33 cites
$34 iucn
$35 redlist
$36 protected
$37 sensitive
$38 kingdom
$39 kingdom_c
$40 phylum
$41 phylum_c
$42 class
$43 class_c
$44 order
$45 order_c
$46 family
$47 family_c
$48 genus
$49 genus_c

可以拿來篩選的欄位有第 3 欄 rank(分類階層,34 為物種,35、37、38、39、40、42 分別對應到不同的種下階層)與第 22 欄 usage_status(是否為接受名)。
因為現在 TaiCOL 僅提供 csv 格式的名錄,其中部分欄位若有多個值,會以雙引號框起來,裡面再以逗號分隔(例如 "節節草, 臺灣木賊, 筆管草, 台灣木賊")。這會造成資料處裡過程中很大的困擾,必須要先處理。
把那些帶有雙引號欄位中的分隔符號改為分號後,我們就可以在 awk 中依序篩選出接受名與需要的分類階層:

sed -e 's/,\"/,/g' -e 's/\",/,/g' -e 's/, /;/g' TaiCOL_name_20230818.csv|\ awk -F, -v OFS="\t" '$21 == "accepted"{print $3, $4, $38, $39, $40, $41, $42, $43, $44, $45, $46, $47, $48, $49, $4, $6, $5, $23, $24, $25, $26, $27, $33, $34, $35, $36, $37, $22}' > acc.TaiCOL_name_20230818.tsv #如果用數字篩選無效的話,改為:awk -F'\t' '$1 == "Species" || $1 == "Subspecies" || $1 == "Variety" || $1 == "Form" || $1 == "Subvariety"\ awk -F'\t' '$1 == "34" || $1 == "35" || $1 == "37" || $1 == "38" || $1 == "39" || $1 == "40" || $1 == "42"\ {printf "sciname[%s]=\"%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\thttps://taicol.tw/taxon/%s\"\n",\ $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28}' acc.TaiCOL_name_20230818.tsv > hash.acc.TaiCOL_name_20230818 #如果不想篩選階層 awk -F'\t' '{printf "sciname[%s]=\"%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\thttps://taicol.tw/taxon/%s\"\n",\ $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24}' acc.TaiCOL_name_20230325.tsv > hash.acc.TaiCOL_name_20230325

可以注意到,印出的格式化字串中,已經把 associative table 的格式編排好了,所以就可以依照用 bash 寫個由學名找物種資訊小功能中的方法來加上開頭的宣告與最後的迴圈,就完成對應新版物種名錄的查找功能了。

cat $1|\
while read -r line; do
        echo -e "$line\t${sciname[$line]}"
done

之後發現 word 有個小功能,可以把 被底線包圍的文字 自動轉為 斜體,對我們的這個物種名錄對應功能來說,應該好好利用。
原本表單中的欄位就有 formatted_name 一項,使用 html 語法來設定學名的格式,所以我們只要把 <i></i> 替換為底線即可:

sed -i 's/<\/\?i>/_/g' queryTaiCOL_name_20230325.sh

測試結果:

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

使用這個小工具,就可以快速比對出調查物種的高階分類群與其他資訊,甚至連學名格式都設定好了。

2024.01.10 更新:
因為 TaiCOL 的學名名錄表格內容順序又變更了,附上最新的處理過程:

wget https://taicol.tw/static/upload/TaiCOL_name_20240104.zip unzip TaiCOL_name_20240104.zip awk 'BEGIN{FS=OFS="\""} {for (i=1; i<=NF; i+=2) gsub(/,/, "|", $i); print}' TaiCOL_name_20240104.csv|\ sed 's/\"//g'|\ awk -F"|" -v OFS="\t" '$22 == "accepted"{print $3, $4, $38, $39, $40, $41, $42, $43, $44, $45, $46, $47, $48, $49, $4, $6, $5, $24, $25, $23, $26, $27, $33, $34, $35, $36, $37, $21}' > acc.TaiCOL_name_20240104.tsv awk -F'\t' '$1 == "34" || $1 == "35" || $1 == "37" || $1 == "38" || $1 == "39" || $1 == "40" || $1 == "42"\ {printf "sciname[%s]=\"%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\thttps://taicol.tw/taxon/%s\"\n",\ $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26, $27, $28}' acc.TaiCOL_name_20240104.tsv > hash.acc.TaiCOL_name_20240104

🐕‍🦺


TaiCOL 名錄裡 rank 的數字與種/種下階層對照:

數字 階層 remark
34 Species
35 Subspecies 亞種
37 Variety 變種,常見於植物
38 Subvariety 亞變種
39 nothovar. 栽培雜交變種
40 Form 型,常見於植物
42 Forma specialis(f.sp.) 寄生專化型

之後從 TaiCOL 獲得了 rank_map 如下可供參考:

1: 'Domain' 2: 'Superkingdom' 3: 'Kingdom' 4: 'Subkingdom'
5: 'Infrakingdom' 6: 'Superdivision' 7: 'Division' 8: 'Subdivision'
9: 'Infradivision' 10: 'Parvdivision' 11: 'Superphylum' 12: 'Phylum'
13: 'Subphylum' 14: 'Infraphylum' 15: 'Microphylum' 16: 'Parvphylum'
17: 'Superclass' 18: 'Class' 19: 'Subclass' 20: 'Infraclass'
21: 'Superorder' 22: 'Order' 23: 'Suborder' 24: 'Infraorder'
25: 'Superfamily' 26: 'Family' 27: 'Subfamily' 28: 'Tribe'
29: 'Subtribe' 30: 'Genus' 31: 'Subgenus' 32: 'Section'
33: 'Subsection' 34: 'Species' 35: 'Subspecies' 36: 'Nothosubspecies'
37: 'Variety' 38: 'Subvariety' 39: 'Nothovariety' 40: 'Form'
41: 'Subform' 42: 'Special Form' 43: 'Race' 44: 'Stirp'
45: 'Morph' 46: 'Aberration' 47: 'Hybrid Formula'