我有一个以下格式的配置文件。
<Title>
[part1]
A.File = a
A.Val = val1
B.File = a
B.Val = val1
[part2]
A.File = a1
A.Val = val2
B.File = a
B.Val = val1
我只想从第一部分中提取值。
#!/bin/sh
getCalibDate()
{
file="/path/of/config/file"
value=`cat ${file} | grep Val | cut -d'=' -f2`
for v in $value
do
echo $v
done
}
getCalibDate
上面的脚本将返回所有值。如何仅从第一部分 (part1) 获取值?
答案1
如果您之后只有 4 行,[part1]
则可以使用-A4
以下选项grep
:
cat ${file} | grep -A4 "part1" | cut -d'=' -f2`
对于一般情况([part1] 之后超过 4 行),用于sed
获取两个部分之间的文本:
cat ${file} | sed -n "/part1/,/part2/p" | head -n-1
head
就是part2
最后删除多余的
作为特登说你不必使用cat
,你可以执行以下操作:
grep -A4 "part1" ${file} | cut -d'=' -f2`
或者:
sed -n "/part1/,/part2/p" ${file} | head -n-1
答案2
您需要使用更复杂的工具来解析该文件。例如,awk
:
#!/bin/sh
getCalibDate()
{
file="${1}"
value=$(awk '/\[part/{a++}(a<2 && /Val/){print $NF}' ${file})
for v in $value
do
echo $v
done
}
getCalibDate ${1}
a
在这里,每当一行匹配 时,变量就会递增[part
。然后,$NF
当一行匹配时,Val
仅当a
小于 2、且位于第一部分时,才会打印最后一个字段 ( )。
答案3
并使用这个:
sed -n -e '/\[part1\]/,/\[part2\]/p' FILE |sed -e '1d;$d'| awk -F "=" '{print $2}'
输出是:
a
val1
a
val1
答案4
这里有一些很好的答案,但我只看到一个包含了Val
问题的一部分的答案,而且这是否正确还不清楚。我同意这awk
是“一个了不起的工具”,但这里没有必要;我相信这个sed
命令:
sed -n '/\[part1\]/,/\[part2\]/s/.*Val.*=//p' "$file"
可能会做所需的事情。就像其他sed -e '/\[part1\]/,/\[part2\]/p'
解决方案一样(网络达人
和宝贝),这可以轻松地适应选择任何部分。 (当然,你需要知道它的名字;如果你只知道它的序数,你可以适应特登的回答
或者格伦·杰克曼的回答,其中两者数数部分而不是寻找特定名称。)如果您不知道以下部分的名称,您可以这样做
sed -n '/\[part42\]/,/\[部分/是...'“$文件”
例如。
我唯一的元问题是关于cut -d'=' -f2
问题的一部分。如果我们从中提取数据的输入行后面包含多个=
字符Val
(即字段值包含=
字符),例如,
Einstein.Val = E=mc^2
那么上面的cut
命令将仅提取第一个和第二个之间的文本=
(即字段值,直到(但不包括)第一个=
),例如 E
。我上面给出的命令sed
将只提取后面的文本最后的 =
(例如,mc^2
)。要获取第一个之后的所有内容=
(例如E=mc^2
),请使用
sed -n '/\[part1\]/,/\[part2\]/s/.*Val[^=]*=//p' "$file"
cut
要模仿(例如)的行为 E
,请使用
sed -n '/\[part1\]/,/\[part2\]/s/.*Val[^=]*=\([^=]*\).*/\1/p' "$file"
请注意,我的方法假设数据至少总体上类似于问题中的插图;即,至少有一个=
出现在字符串右侧的某处Val
。因此,我的所有解决方案都会忽略输入,例如
Girl.Name = Valerie
Valerie Bertinelli
即使它落在[part1]
和之间[part2]
。