Linux脚本读取ini文件并按指定字符拆分为变量
我被困在以下任务中:让我们假设文件夹中有一个Linux脚本读取ini文件并按指定字符拆分为变量,linux,Linux,我被困在以下任务中:让我们假设文件夹中有一个.ini文件。该文件包含如下行: eno1=10.0.0.254/24 eno2=172.16.4.129/25 eno3=192.168.2.1/25 tun0=10.10.10.1/32 我必须选择最大的子网掩码。所以我的尝试是: declare -A data for f in datadir/name do while read line do r=(${line//=/ }) let data[${r[0]}]=${r
.ini
文件。该文件包含如下行:
eno1=10.0.0.254/24
eno2=172.16.4.129/25
eno3=192.168.2.1/25
tun0=10.10.10.1/32
我必须选择最大的子网掩码。所以我的尝试是:
declare -A data
for f in datadir/name
do
while read line
do
r=(${line//=/ })
let data[${r[0]}]=${r[1]}
done < $f
done
declare-A数据
对于datadir/name中的f
做
读行时
做
r=(${line/=/})
让数据[${r[0]}]=${r[1]}
完成<$f
完成
这就是我走了多远。(是的,我知道名为name的文件不是.ini
文件,而是.txt
文件,因为我在创建ini文件时遇到了问题,所以这位老师甚至没有为我们的考试提供这样的文件。)
它将行拆分为=,但由于(第一个)的原因,它不想读取IP号。性格
(我收到的错误消息中的算术运算符无效)
如果有人能帮助我,并解释我如何为这样的任务制作脚本,我将非常感谢 不要使用
让。这是算术课
$ help let
let: let arg [arg ...]
Evaluate arithmetic expressions.
Evaluate each ARG as an arithmetic expression.
只需使用直接赋值:
declare-A数据
对于datadir/name中的f
做
读行时
做
r=(${line/=/})
数据[${r[0]}]=${r[1]}
完成<$f
完成
结果:
$ declare -p data
declare -A data=([tun0]="10.10.10.1/32" [eno1]="10.0.0.254/24" [eno2]="172.16.4.129/25" [eno3]="192.168.2.1/25" )
不要使用让
。这是算术课
$ help let
let: let arg [arg ...]
Evaluate arithmetic expressions.
Evaluate each ARG as an arithmetic expression.
只需使用直接赋值:
declare-A数据
对于datadir/name中的f
做
读行时
做
r=(${line/=/})
数据[${r[0]}]=${r[1]}
完成<$f
完成
结果:
$ declare -p data
declare -A data=([tun0]="10.10.10.1/32" [eno1]="10.0.0.254/24" [eno2]="172.16.4.129/25" [eno3]="192.168.2.1/25" )
awk
提供了一个简单的解决方案,用于查找'/'
后面的最大值,该值将比bash脚本或Unix管道快几个数量级,使用:
awk -F"=|/" '$3 > max { max = $3 } END { print max }' file
示例使用/输出
$ awk -F"=|/" '$3 > max { max = $3 } END { print max }' file
32
上面的awk
使用'='
或'/'
作为字段分隔符分隔字段,然后保持第三个字段$3的最大值,并使用结束{…}
规则输出该值
Bash解决方案
如果确实需要bash脚本解决方案,则可以使用[[..=~]]
来隔离每行所需的部分,以填充bash\u REMATCH
数组,然后将${bash\u REMATCH[3]}
与max
变量进行比较。带有=~
的[[…]]
表达式将右侧的所有内容视为扩展正则表达式,并将每个分组((…)
)隔离为数组BASH_REMATCH
中的一个元素,例如
#!/bin/bash
[ -z "$1" ] && { printf "filename required\n" >&2; exit 1; }
declare -i max=0
while read -r line; do
[[ $line =~ ^(.*)=(.*)/(.*)$ ]]
((${BASH_REMATCH[3]} > max)) && max=${BASH_REMATCH[3]}
done < "$1"
printf "max: %s\n" "$max"
(两个shell脚本解决方案的输出相同)
如果您还有其他问题,请与我联系。awk
提供了一个简单的解决方案,用于查找'/'
后面的最大值,该值将比bash脚本或Unix管道快几个数量级,使用:
awk -F"=|/" '$3 > max { max = $3 } END { print max }' file
示例使用/输出
$ awk -F"=|/" '$3 > max { max = $3 } END { print max }' file
32
上面的awk
使用'='
或'/'
作为字段分隔符分隔字段,然后保持第三个字段$3的最大值,并使用结束{…}
规则输出该值
Bash解决方案
如果确实需要bash脚本解决方案,则可以使用[[..=~]]
来隔离每行所需的部分,以填充bash\u REMATCH
数组,然后将${bash\u REMATCH[3]}
与max
变量进行比较。带有=~
的[[…]]
表达式将右侧的所有内容视为扩展正则表达式,并将每个分组((…)
)隔离为数组BASH_REMATCH
中的一个元素,例如
#!/bin/bash
[ -z "$1" ] && { printf "filename required\n" >&2; exit 1; }
declare -i max=0
while read -r line; do
[[ $line =~ ^(.*)=(.*)/(.*)$ ]]
((${BASH_REMATCH[3]} > max)) && max=${BASH_REMATCH[3]}
done < "$1"
printf "max: %s\n" "$max"
(两个shell脚本解决方案的输出相同)
如果您还有其他问题,请告诉我。前面介绍的两种解决方案都可以运行(并执行它们设计的功能);我想我应该在左栏添加一些东西,因为规格相当宽松
$ cat freasy
eno1=10.0.0.254/24
eno2=172.16.4.129/25
eno3=192.168.2.1/25
tun0=10.10.10.1/32
我认为最大的子网掩码是数值最低的子网掩码(容纳最多的主机)
之前提出的两种解决方案都可以运行(并实现其设计目标);我想我应该在左栏添加一些东西,因为规格相当宽松
$ cat freasy
eno1=10.0.0.254/24
eno2=172.16.4.129/25
eno3=192.168.2.1/25
tun0=10.10.10.1/32
我认为最大的子网掩码是数值最低的子网掩码(容纳最多的主机)
你如何比较IP号码?是什么使一个比另一个大?子网掩码是斜杠后面的部分。最大的子网掩码是斜杠后最大值的IP地址。如何比较IP号码?是什么使一个比另一个大?子网掩码是斜杠后面的部分。最大的子网掩码将是斜杠后具有最大值的IP地址。这似乎是bash
编程分配,因此可能会排除实用程序。如果没有,可以使用sort-t'/'-k2-r-ndatadir/name | head-1 | cut-d'/'-f2
`它被标记为[linux]
,这样就可以覆盖linux实用程序,比如sort
或awk
。管道而不是单个进程的唯一缺点是为每个实用程序和管道生成子shell。对于效率显著不同的大型文件。这似乎是一个bash
编程任务,因此可能会排除实用程序。如果没有,可以使用sort-t'/'-k2-r-ndatadir/name | head-1 | cut-d'/'-f2
`它被标记为[linux]
,这样就可以覆盖linux实用程序,比如sort
或awk
。管道而不是单个进程的唯一缺点是为每个实用程序和管道生成子shell。对于具有显著效率差异的大型文件。