澳门新萄京官方网站-www.8455.com-澳门新萄京赌场网址

澳门新萄京官方网站read命令产生硬编码问题解决

2019-10-01 作者:澳门新萄京官方网站   |   浏览(106)

情景

咱俩明白,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命令产生硬编码问题解决,如何解决read命令产生的硬编码问题。不知你意识未有,那样的兑现格局具备鲜明的坏处:

  1. 列名(read index number name age)显式地在代码中钦点,要是只是想弄领会数据文件的每列含义,则需求阅读脚本;
  2. 该脚本中指明了每列的名称,假诺期待修改各字段的英文名称(譬喻序号的朝鲜语名称希望改为NUMBER)则必要修改剧本,且修改多处;
  3. 该脚本按自然顺序读取数据文件,因此,如果数据文件中的列顺序爆发了扭转,则照旧须要修改脚本;
  4. 只要有任何数据文件供给按此方法读取,则须要基于数据文件的实际上意况再重写二个新本子;

上述达成形式固然看起来大约,但依赖上述的害处,我们还应对其开展优化。

情景

我们知晓,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

不知你意识未有,那样的兑现格局具有刚强的流弊:

  1. 列名(read index number name age)显式地在代码中钦定,假如只是想弄明白数据文件的每列含义,则须要阅读脚本;
  2. 该脚本中指明了每列的名目,即使愿意修改各字段的斯洛伐克语名称(比如序号的塞尔维亚共和国(Republic of Serbia)语名称希望改为NUMBER)则需求修改剧本,且修改多处;
  3. 该脚本按自然顺序读取数据文件,由此,假若数据文件中的列顺序发生了扭转,则依旧须求修改脚本;
  4. 一旦有别的数据文件须求按此方法读取,则须要依据数据文件的实际上情状再重写一个新影片本;

上述实现格局就算看起来简单,但基于上述的弊病,大家还应对其张开优化。

a. 盘算工作 marks.txt 本文件有4列

1)    Amit     Physics    80
2)    Rahul    Maths      90
3)    Shyam    Biology    87
4)    Kedar    English    85
5)    Hari     History    89

marks2.txt 本文件有部分列有5列

1)    Andy     Physics    80
2)    Jacky    Maths      90    10
3)    Hill    Biology    87
4)    John    English    85 12
5)    Mary     History

方案

缓慢解决的常有应该是写尽可能通用的脚本,不借助数据文件自身的列数、列顺序、列名称(含义)等。

能够将数据文件的各字段名称存于该数据文件的首行。当读取数据文件时,首先读取数据文件的首行,以博取各字段名称的列表;读取其余行时,将首行的值与非首行的值实行各个对应就能够。

数据文件

$ 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

澳门新萄京官方网站,要写出更通用的剧本,还是能做一些料定和管理,举个例子:数据文件作为参数字传送入、检查数据文件的行数、检查数据文件的列数,等等。

方案

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

能够将数据文件的各字段名称存于该数据文件的首行。当读取数据文件时,首先读取数据文件的首行,以取得各字段名称的列表;读取另外行时,将首行的值与非首行的值实行依次对应就能够。

数据文件

$ 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

要写出更通用的脚本,仍是可以够做一些论断和管理,比如:数据文件作为参数字传送入、检查数据文件的行数、检查数据文件的列数,等等。

b. 样例

  • (1).文本加标题行 "序号 姓名 科目 分数" 展现:
>awk 'BEGIN {printf "序号t姓名t科目t分数n"} {print}' marks.txt 

序号  姓名  科目  分数
1)    Amit     Physics    80
2)    Rahul    Maths      90
3)    Shyam    Biology    87
4)    Kedar    English    85
5)    Hari     History    89
  • (2).实行awk脚本:将单引号内的本子写到多个文件,然后通过 -f 援引文件实行:
> cat command.awk 
BEGIN {printf "序号t姓名t科目t分数n"} {print}

> awk -f command.awk marks.txt
序号  姓名  科目  分数
1)    Amit     Physics    80
2)    Rahul    Maths      90
3)    Shyam    Biology    87
4)    Kedar    English    85
5)    Hari     History    89
  • (3). -v声称一个变量的值,BEGIN前分配
> awk -v user=root 'BEGIN{printf "name=%sn", user}' `
name=root
  • (4). 计算: - * / %
> awk 'BEGIN {a=52; b=50; print "a%b=", (a%b)}'  `
a%b= 2
  • (5). BEGIN END 定义变量a,在管理行的长河中增添(能够与行内的内容举办测算),END时输出:(总括总分数)
>awk 'BEGIN { sumScore = 0; printf "总分数sumScore = %dn", a } {sumScore=sumScore $NF;print} END{print ">总分数sumScore=",sumScore}' marks.txt`
总分数sumScore = 0
1)    Amit     Physics    80
2)    Rahul    Maths      90
3)    Shyam    Biology    87
4)    Kedar    English    85
5)    Hari     History    89
>总分数sumScore= 431

澳门新萄京官方网站 1

疲劳的分水岭


扩大知识

从剧本的改进上看,比原脚本略显复杂,但却特别通用了。
一旦以为阅读脚本吃力,能够有针对地读书下,特别是以下知识点:

  • 数组的相干文化:数首席试行官度、数组内容、数组成分等
  • 变量${abc}${!abc}的区别

扩充知识

从剧本的改进上看,比原脚本略显复杂,但却愈发通用了。
即便感觉阅读脚本吃力,可以有指向地上学下,尤其是以下知识点:

  • 数组的连锁文化:数老板度、数组内容、数组成分等
  • 变量${abc}${!abc}的区别

正文恒久更新链接地址:http://www.linuxidc.com/Linux/2017-06/145163.htm

澳门新萄京官方网站 2

awk内置变量: NR FNR NF

NR = Number of Records
NF = Number of Fields
FNR = File Number of Records
上边摘自: The GNU Awk User’s Guide

awk divides the input for your program into records and fields. It keeps track of the number of records that have been read so far from the current input file. This value is stored in a predefined variable called FNR, which is reset to zero every time a new file is started. Another predefined variable, NR, records the total number of input records read so far from all data files. It starts at zero, but is never automatically reset to zero.
......
The value of the built-in variable NF is the number of fields in the current record.

翻译与计算
awk将顺序的输入分为记录和字段。
它追踪从脚下输入文件到近来截止已经读取的记录数据。

FNR 该值存款和储蓄在一个名叫FNCRUISER的预订义变量中,每运营贰个新文件时,该变量将重新初始化为零。【每行的行号-单个文件

NR 另三个预约义变量N安德拉记录从有着数据文件中读取的输入记录总的数量。 它从零初叶,但 从不 自动重新设置为零。【每行的行号-全部文件

NF 内置变量NF的值是当前记下中的字段数。在执行块中$NF可以得到当前行末字段的值

  • (6). 打字与印刷全局行号 当前行号 行内列数 行末字段值
> awk 'BEGIN{print "全局行号t当前行号t行内列数t行末字段值"} {print NR,"t", FNR,"t", NF,"t", $NF}' marks.txt marks2.txt

全局行号    当前行号    行内列数    行末字段值
1    1   4   80
2    2   4   90
3    3   4   87
4    4   4   85
5    5   4   89
6    1   4   80
7    2   5   10
8    3   4   87
9    4   5   12
10   5   3   History

澳门新萄京官方网站 3

疲劳分水岭

本文由澳门新萄京官方网站发布于澳门新萄京官方网站,转载请注明出处:澳门新萄京官方网站read命令产生硬编码问题解决

关键词: