我們知道,read指令可以讀取檔案內容,並且把內容賦值給變數。
以如下的資料檔為例。
$ cat data.txt
1 201623210021 wangzhiguo 25 2 201623210022 yangjiangbo 26 3 201623210023 yangzhen 24 4 201623210024 wangdong 23 5 201623210025 songdong 25
以上文件的四列分別為序號(index)、學號(number)、姓名(name)、年齡(age)。用shell腳本讀取該檔案並輸出每行的值:
$ cat read_data.sh
#!/bin/bash cat data.txt | while read index number name age do echo "index:${index}" echo "number:${number}" echo "name:${name}" echo "age:${age}" echo " " done
執行腳本,檢視結果:
$ sh read_data.sh
index:1 number:201623210021 name:wangzhiguo age:25 index:2 number:201623210022 name:yangjiangbo age:26 index:3 number:201623210023 name:yangzhen age:24 index:4 number:201623210024 name:wangdong age:23 index:5 number:201623210025 name:songdong age:25
不知你發現沒有,這樣的實作方式有著明顯的弊端:
列名(read index number name age)明確地在程式碼中指定,如果只是想弄清楚資料檔案的每列意義,則需要閱讀腳本;
該腳本中指明了每個欄位的名稱,如果希望修改各欄位的英文名稱(例如序號的英文名稱希望改為NUMBER
)則需要修改腳本,且修改多處;
該腳本按一定順序讀取資料文件,因此,如果資料檔案中的列順序發生了變化,則依然需要修改腳本;
#如果有其他資料檔案需要以此方式讀取,則需要根據資料檔案的實際情況再重寫一個新腳本;
上述實作方式雖然看起來簡單,但基於上述的弊端,我們也應對其進行優化。
解決的根本應該是寫盡可能通用的腳本
,不依賴資料檔案本身的列數、列順序、列名稱(意義)等。
可以將資料檔案的各欄位名稱存於該資料檔案的首行。當讀取資料檔案時,首先讀取資料檔案的首行,以取得各欄位名稱的清單;讀取其它行時,將首行的值與非首行的值進行一一對應即可。
資料檔
$ cat new_data.txt
index number name age 1 201623210021 wangzhiguo 25 2 201623210022 yangjiangbo 26 3 201623210023 yangzhen 24 4 201623210024 wangdong 23 5 201623210025 songdong 25
腳本
$ cat new_read_data.sh
#!/bin/bash # 读取文件头行,存于一个数组中 tablehead=(`head -n 1 new_data.txt`) # 从文件第二行开始读取,按上述数组顺序读取各字段 tail -n +2 new_data.txt | while read ${tablehead[*]} do # 遍历数组的下标,获取tablehead数组的对应值,以及以该值命名的变量的值 for i in `seq 0 $((${#tablehead[@]}-1))` do temp=${tablehead[$i]} echo "${temp}:${!temp}" done echo "" done
結果
$ sh new_read_data.sh
index:1 number:201623210021 name:wangzhiguo age:25 index:2 number:201623210022 name:yangjiangbo age:26 index:3 number:201623210023 name:yangzhen age:24 index:4 number:201623210024 name:wangdong age:23 index:5 number:201623210025 name:songdong age:25
要寫出更通用的腳本,還可以做一些判斷和處理,例如:數據檔案作為參數傳入、檢查資料檔案的行數、檢查資料檔案的列數,等等。
從腳本的改進來看,比原腳本略顯複雜,但卻更通用了。
如果覺得閱讀腳本吃力,可以有針對性地學習下,尤其是以下知識點:
#數組的相關知識:數組長度、數組內容、數組元素等
變數${abc}
和${!abc}
的差異
以上是情境linux--read指令產生的硬編碼問題怎麼解決?的詳細內容。更多資訊請關注PHP中文網其他相關文章!