read コマンドはファイルの内容を読み取り、その内容を変数に代入できることがわかっています。
次のデータファイルを例として取り上げます。
$ cat data.txt
1 201623210021 wangzhiguo 25 2 201623210022 yangjiangbo 26 3 201623210023 yangzhen 24 4 201623210024 wangdong 23 5 201623210025 songdong 25
上記ファイルの 4 つの列は、シリアル番号 (インデックス)、学生番号 (番号)、名前 (名前)、年齢 (年齢) です。シェル スクリプトを使用してファイルを読み取り、各行の値を出力します:
$ 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
この実装には明らかな欠点があることに気づいたでしょうか:
列名 (データ ファイルの各列の意味を理解したいだけの場合は、スクリプトを読む必要があります。各列の名前は、各フィールドの英語名を変更する場合 (たとえば、シリアル番号の英語名を NUMBER
に変更する場合)、スクリプトの多くの場所を変更する必要があります。
スクリプトは特定の順序でデータ ファイルを読み取るため、データ ファイル内の列の順序が変更された場合でも、スクリプトを変更する必要があります。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}
可能な限り汎用性の高いスクリプトを作成する
ことであり、列の数、列の順序、列名(意味)などに依存しないようにする必要があります。データファイル自体。 🎜🎜データファイルの最初の行にデータファイルのフィールド名を保存できます。データファイルを読み取るときは、まずデータファイルの最初の行を読んでフィールド名のリストを取得し、他の行を読み取るときは、最初の行の値とその値を 1 対 1 に対応させます。最初の行以外の行。 🎜🎜データファイル🎜rrreeerrreee🎜スクリプト🎜rrreeerrreee🎜Result🎜rrreeerrreee🎜 より一般的なスクリプトを作成するには、データファイルをパラメータとして渡したり、データファイルの行数をチェックしたりするなど、いくつかの判断と処理を行うこともできます。データファイル、データファイルの列数の確認など。 🎜🎜知識を広げる🎜🎜 スクリプトの改善から判断すると、元のスクリプトよりも若干複雑ですが、より汎用性が高くなります。 ${abc}
と ${!abc}
の違い🎜🎜🎜以上がシナリオ Linux -- read コマンドによって引き起こされるハードコーディングの問題を解決するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。