# 用 bash 寫個由學名找物種資訊小功能 ###### tags: `ubuntu` `學習筆記` `bash` 最近的工作需要用到[台灣物種名錄](https://taibnet.sinica.edu.tw/home.php?)(Catalogue of Life in Taiwan,就是以前的臺灣生物多樣性國家資訊網 Taiwan Biodiversity National Information Network, TaiBNET,為了和[臺灣生物多樣性國家入口網站](https://portal.taibif.tw/) Taiwan Biodiversity Information Facility, TaiBIF 區隔而改中文名)整合的物種分類階層、原生種、保育類、紅皮書等資料來整理每次生態調查到的資料。一樣的事情需要做超過 3 次的話,還是考慮搭配程式來做比較省時,因此就試著用 bash 裡的關聯陣列(associative array)功能來做。 在 bash 4.2 版之後,就有了 associative array 功能。現在大部分的 ubuntu 中都在 4.2 版之後,若要確認,使用 ```bash $ bash --version ``` 確定版本後,就可以準備開始製作 associative array。 定義方式有以下 2 種: ```bash $ declare -A assArray1 $ assArray1[dog]=woof $ assArray1[cat]=meow $ assArray1[tiger]=roar $ declare -A assArray2=( [H]=hydrogen [He]=helium [Li]=lithium ) ``` 呼叫有以下幾種方式: ```bash $ 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[學名]=該學名的資料` 這種形式。 確定好就可以把資料載下來處理了。 ```bash! $ wget https://taibnet.tw/static/upload/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,隨便抽一行出來,長成這樣: ```bash! 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。 最後可以寫一個迴圈來大量處理學名,生成資料: ```bash! cat $1|\ while read -r line; do echo -e "$line\t${sciname[$line]}"| sed 's/\]\[/\t/g' done ``` 第一個欄位還是貼上需要查詢的學名,萬一沒對到,到時輸出表單還可以手動填上。 隨便找 5 個學名來試看看 ```bash! $ cat test Dissomphalus wusheanus Pristepyris zhejiangensis Abrocythereis feishania Abudefduf sordidus Acanthaster planci ``` 最後輸出結果: ```bash! 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 ``` <span style="font-size:30px">🐕🦺</span>2022.12.07
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up