我有一个配置文件:
a: 123
b: abc
device: 1000
c: xyz
[old]
a: 120
b: xyz
device: 200
c: abc
“[old]”部分及其下面的所有内容并不总是存在。
如何确定文件中可选的“[old]”部分之前是否存在文本“device: 1000”?
我一直在摆弄以下(损坏的)命令语法,但我无法让它执行我需要的操作......
sed -e '0,/^\[/; /device: /p' configfile ; echo $?
...其中0,/^\[/
应该限制文件开头和第一列中第一次出现“[”之间的搜索。我试图获取返回码来指示是否找到该字符串。
答案1
如果awk
是一个选项:
awk 'BEGIN{o=d=1} /\[old\]/{o=0} /device: 1000/&&o==1{d=0;exit} END{exit d}' file
解释:
BEGIN{o=d=1}
:初始化变量/\[old\]/{o=0}
if[old]
: 被发现已设置o=0
/device: 1000/&&o==1{d=0;exit}
:如果device: 1000
找到并且[old]
尚未找到,则设置d=0
并跳转到该END{}
块,而不进一步检查文件。END{exit d}
:以给定值退出d
像这样运行它:
awk 'BEGIN{o=d=1} /\[old\]/{o=0} /device: 1000/&&o==1{d=0;exit} END{exit d}' file && echo "contains" || echo "contains not"
答案2
我通常通过将多行捕获到一个变量来使用 sed 创建一个 blob。如果满足所需的条件,则可以稍后进行检查。
blob=“$(sed -n “/^abc.*$/,/^$/p” file)”
现在我们已将文件的顶部部分分配给”${blob}”
.
现在我们只是有条件地检查${blob}
是否[old]
存在:
sh if [ $(grep -c “^\[old/]$” file) -gt 0 ]; then echo “${blob}” | grep “^device” | grep -c 1000 fi
我确信这可以被重构,但这会给你你想要的结果。
答案3
device: 1000
您可以在删除之后的所有内容后查找[old]
:
if sed '/^\[old\]/q' < file | grep -q 'device: 1000'; then
echo OK
fi
使用 GNU (考虑到您的方法中sed
特定于 GNU 的情况,您似乎正在使用 GNU )。0,/.../
if sed -n '/device: 1000/q; /^\[old\]/Q1' < file; then
echo OK
fi
( ,以 0(成功)退出状态退出q
的标准形式,而以退出状态 1(非零,因此不成功)退出)。Q0
Q1
使用 standard sed
,您无法更改sed
的退出状态,但您可以依赖它是否输出某些内容:
if [ -n "$(sed -n '/^\[old\]/q;/device: 1000/!d;=;q' < file)" ]; then
echo OK
fi
(其中=
输出第一次出现 的行号device: 1000
)。
或者您可以使用awk
它可以便携式地设置退出状态:
if awk '$0 == "[old]" {exit 1}; /device: 1000/ {exit 0}' < file; then
echo OK
fi