2021-05-12 14:32:11
Linux read命令產生寫死問題解決
2020-06-16 17:11:51
情景
我們知道,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}
的區別
本文永久更新連結地址:http://www.linuxidc.com/Linux/2017-06/145163.htm
相關文章