Try   HackMD

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

tags: ubuntu 學習筆記 bash

最近的工作需要用到台灣物種名錄(Catalogue of Life in Taiwan,就是以前的臺灣生物多樣性國家資訊網 Taiwan Biodiversity National Information Network, TaiBNET,為了和臺灣生物多樣性國家入口網站 Taiwan Biodiversity Information Facility, TaiBIF 區隔而改中文名)整合的物種分類階層、原生種、保育類、紅皮書等資料來整理每次生態調查到的資料。一樣的事情需要做超過 3 次的話,還是考慮搭配程式來做比較省時,因此就試著用 bash 裡的關聯陣列(associative array)功能來做。

在 bash 4.2 版之後,就有了 associative array 功能。現在大部分的 ubuntu 中都在 4.2 版之後,若要確認,使用

$ bash --version

確定版本後,就可以準備開始製作 associative array。
定義方式有以下 2 種:

$ declare -A assArray1
$ assArray1[dog]=woof
$ assArray1[cat]=meow
$ assArray1[tiger]=roar

$ declare -A assArray2=( [H]=hydrogen [He]=helium [Li]=lithium )

呼叫有以下幾種方式:

$ echo ${assArray1[dog]}
$ woof

$ echo ${#assArray1[cat]}
$ 4

$ echo ${!assArray2[@]}
H Li He

$ echo ${assArray2[@]}
hydrogen lithium helium

$ echo ${#assArray2[@]}
3

用法大概是這樣。接著就可以把台灣物種名錄處理成 associative array 的定義方式了。先思考所需要輸入的 key 應該要是物種的學名,輸出的 value 是台灣物種名錄有關該學名的所有資料,所以定義的時候應該要寫成 array_name[學名]=該學名的資料 這種形式。
確定好就可以把資料載下來處理了。

$ wget https://taibnet.sinica.edu.tw/download/TaiwanSpecies20221230_UTF8.txt.zip
$ unzip TaiwanSpecies20221230_UTF8.txt.zip
#只保留現行接受名,且將第12行的學名複製到第一行,以**區隔;學名資料中的 tab 仍然保留
$ awk -F"\t" -v OFS="**" '$24!~0 {print $12,$0}' taiwan-species.txt > acc.taiwan-species
#要養成備份好習慣喔
$ cp acc.taiwan-species acc.taiwan-species2206.orig
#把學名資料中的tab換掉、學名前加上sciname[、學名後加上]="、行末加上"
$ sed -e 's/\t/\]\[/g' -e 's/^/sciname[/g' -e 's/\*\*/]="/g' -e 's/$/"/g' -e 's/NULL//g' acc.taiwan-species > hash-acc.taiwan-species

到這邊就完成了 associative table,隨便抽一行出來,長成這樣:

sciname[Telchinia issoria formosana]="Animalia][動物界][Arthropoda][節肢動物門][Insecta][昆蟲綱][Lepidoptera][鱗翅目][Nymphalidae][蛺蝶科][444909][Telchinia issoria formosana][Telchinia][][issoria][][formosana][][][(Fruhstorfer, 1912)][][444909][1][1][0][][0][0][苧麻細蝶;苧麻珍蝶;苧麻蝶;細蝶][][][][][][][][][][][][2022-06-03"

用肉眼看起來,][ 取代 tab 的效果相當不錯,看起來就是一個一個的欄位資料用中括號框起來。
若要查詢且輸出,可以用 echo ${sciname[要查詢的學名]} 來找,再用 sed 's/\]\[/\t/g' 把原本用以區隔的 ][ 符號換成 tab。

最後可以寫一個迴圈來大量處理學名,生成資料:

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

第一個欄位還是貼上需要查詢的學名,萬一沒對到,到時輸出表單還可以手動填上。

隨便找 5 個學名來試看看

$ cat test
Dissomphalus wusheanus
Pristepyris zhejiangensis
Abrocythereis feishania
Abudefduf sordidus
Acanthaster planci

最後輸出結果:

Dissomphalus wusheanus  Animalia        動物界  Arthropoda      節肢動物門      Insecta 昆蟲綱  Hymenoptera     膜翅目  Bethylidae      蟻形蜂科        445807  Dissomphalus wusheanus  Dissomphalus    寬腹蟻形
蜂屬    wusheanus                                       Terayama, 2001          445807  1       1       0       0       0       0       霧社寬腹蟻形蜂                                                          2022-06-21
Pristepyris zhejiangensis       Animalia        動物界  Arthropoda      節肢動物門      Insecta 昆蟲綱  Hymenoptera     膜翅目  Bethylidae      蟻形蜂科        445811  Pristepyris zhejiangensis       Pristepyris      鋸蟻形蜂屬      zhejiangensis                                   (Terayama et al., 2002)         445811  1       1       0       0       0       0       浙江鋸蟻形蜂                                    2022-06-21
Abrocythereis feishania Animalia        動物界  Arthropoda      節肢動物門      Ostracoda       介形蟲綱        Podocopida      速足介目        Trachyleberididae       粗面介科        409530  Abrocythereis feishania  Abrocythereis   艷花介屬        feishania                                       Hu et Tao               409530  1       1       0       1       0               非善艷花介                              2009-09-03
Abudefduf sordidus      Animalia        動物界  Chordata        脊索動物門      Actinopterygii  條鰭魚綱        Perciformes     鱸形目  Pomacentridae   雀鯛科  382311  Abudefduf sordidus      Abudefduf
豆娘魚屬        sordidus                                        (Forsskål, 1775)                382311  1       1       0       1       0       0       梭地豆娘魚;豆娘魚;厚殼仔;梭地雀鯛                       LC               2010-11-15      188467                                  2012-08-27
Acanthaster planci      Animalia        動物界  Echinodermata   棘皮動物門      Asteroidea      海星綱  Valvatida       有瓣目  Acanthasteridae 長棘海星科      313227  Acanthaster planci      Acanthaster
長棘海星屬      planci                                  (Linnaeus)              313227  1       1       0       1       0       0       棘冠海星                                                                2007-11-17

🐕‍🦺2022.12.07