シナリオ Linux -- read コマンドによって引き起こされるハードコーディングの問題を解決するにはどうすればよいですか?

PHP中文网
リリース: 2017-06-21 11:48:35
オリジナル
1684 人が閲覧しました

シナリオ

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
ログイン後にコピー

この実装には明らかな欠点があることに気づいたでしょうか:

  1. 列名 (データ ファイルの各列の意味を理解したいだけの場合は、スクリプトを読む必要があります。各列の名前は、各フィールドの英語名を変更する場合 (たとえば、シリアル番号の英語名を NUMBER に変更する場合)、スクリプトの多くの場所を変更する必要があります。

  2. スクリプトは特定の順序でデータ ファイルを読み取るため、データ ファイル内の列の順序が変更された場合でも、スクリプトを変更する必要があります。NUMBER)则需要修改脚本,且修改多处;

  3. 该脚本按一定顺序读取数据文件,因此,如果数据文件中的列顺序发生了变化,则依然需要修改脚本;

  4. 如果有其他数据文件需要按此方式读取,则需要根据数据文件的实际情况再重写一个新脚本;

上述实现方式虽然看起来简单,但基于上述的弊端,我们还应对其进行优化。

方案

解决的根本应该是写尽可能通用的脚本,不依赖数据文件本身的列数、列顺序、列名称(含义)等。

可以将数据文件的各字段名称存于该数据文件的首行。当读取数据文件时,首先读取数据文件的首行,以获取各字段名称的列表;读取其它行时,将首行的值与非首行的值进行一一对应即可。

数据文件

$ 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 サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート