我有一个带有示例数据的文本文件'builds.txt',如下所示。我只想知道MARX_BUILD号码,即12.我怎样才能实现它。
我尝试了grep MARX_BUILD builds.txt
,它给出了MARX_BUILD = 12。
AM_BUILD_NO=1500
KJI_BUILD_NO=374
LINE_BUILD_NO=365
MARX_BUILD_NO=12
答案 0 :(得分:8)
你已经是那里的一部分了,所以一个选项就是将你的输出输出到cut:
grep MARX_BUILD builds.txt | cut -d= -f2
这会分割=
上的一行并打印第二个字段。
就个人而言,我会使用awk一次性完成整个事情:
awk -F= '/MARX_BUILD/ { print $2 }' builds.txt
这样做相同但只使用一个工具而不是两个。
答案 1 :(得分:3)
执行此操作有3种方法,无需外部二进制文件(例如sed,grep,awk或其他人。)
如果您信任该文件的来源,则可以来源:
source builds.txt
echo $KJI_BUILD_NO
374
如果稍强一点,这种方法会更加安全。
declare -A AArray
while IFS== read var val ;do
[[ "$var" =~ ^[A-Za-z_]*$ ]] && AArray[$var]=$val
done <builds.txt
echo ${AArray[MARX_BUILD_NO]}
12
与之前一样,此方法比eval
更安全,如果您只需要在配置文件中访问一个字段,那么您可以:
ans=$(<builds.txt)
ans=${ans#*LINE_BUILD_NO=}
ans=${ans%%[${IFS}]*}
echo $ans
365
或
field=KJI_BUILD_NO
ans=$(<builds.txt);ans=${ans#*${field}=};ans=${ans%%[${IFS}]*};echo $ans
374
我更喜欢避免 forks 以提高执行脚本的速度。
让我们展示一些差异(在我的主持人身上),速度有一点分类:
time for ((i=1000;i--;));do . builds.txt ;done;echo $MARX_BUILD_NO
0.044s
12
declare -A AArray
time for ((i=1000;i--;)) ;do
while IFS== read var val ;do
[[ "$var" =~ ^[a-zA-Z0-9_]*$ ]] && AArray[$var]=$val
done <builds.txt
done ;echo ${AArray[MARX_BUILD_NO]}
0.356s
12
grep -Po
time for ((i=1000;i--;));do ans=$(
grep -Po '^MARX_BUILD_NO=\K\d*$' builds.txt);done;echo $ans
1.406s
12
sed
time for ((i=1000;i--;));do ans=$(
sed -ne 's/MARX_BUILD_NO=//p' builds.txt);done;echo $ans
1.454s
12
awk
time for ((i=1000;i--;));do ans=$(
awk -F= '/MARX_BUILD_NO/{print $2}' builds.txt);done;echo $ans
2.089s
12
grep | cut
time for ((i=1000;i--;));do ans=$(
grep MARX_BUILD_NO builds.txt | cut -d '=' -f2)
done;echo $ans
2.292s
12
显然,由于 fork 和 pipe ,最后一种方法需要花费大量时间,因此必须为每个变量赋值运行两个新的独立进程。
答案 2 :(得分:1)
如果grep
支持PCRE,您可以执行以下操作:
grep -Po '^MARX_BUILD_NO=\K\d*$' builds.txt
或sed
:
sed -n 's/^MARX_BUILD_NO=\([0-9]*\)$/\1/p' builds.txt
答案 3 :(得分:1)
如果你的grep不支持PCRE,你可以
grep MARX_BUILD_NO builds.txt | cut -d '=' -f2