0

I have a config file thus:

a: 123
b: abc
device: 1000
c: xyz

[old]
a: 120
b: xyz
device: 200
c: abc

The section "[old]" and everything below it is not always present.

How do I determine if the text "device: 1000" exists in the file BEFORE an optional "[old]" section?

I have been messing around with the following (broken) command syntax and I can't get it to do what I need...

sed -e '0,/^\[/;  /device: /p' configfile ; echo $?

...where 0,/^\[/ was supposed to limit the search between the start of the file and the first occurrence of "[" in the first column. I am trying to get the return code to indicate whether the string was found or not.

3 Answers 3

0

If awk is an option:

awk 'BEGIN{o=d=1} /\[old\]/{o=0} /device: 1000/&&o==1{d=0;exit} END{exit d}' file

Explanation:

  • BEGIN{o=d=1}: initialize the variables
  • /\[old\]/{o=0} if [old]: is found set o=0
  • /device: 1000/&&o==1{d=0;exit}: if device: 1000 is found and [old] is not found yet, set d=0 and jump to the END{} block without examining the file further.
  • END{exit d}: exit with the given value of d

Run it like this:

awk 'BEGIN{o=d=1} /\[old\]/{o=0} /device: 1000/&&o==1{d=0;exit} END{exit d}' file && echo "contains" || echo "contains not"
1
  • That'll do nicely. It's about time I learned awk anyway :) Commented Oct 26, 2018 at 12:32
0

I typically create a blob with sed by capturing multiple lines to a variable. This allows an inspection later if the required conditional is met.

blob=“$(sed -n “/^abc.*$/,/^$/p” file)”

Now we have the top portion of the file assigned to ”${blob}”.

Now we just conditionally inspect ${blob} of [old] exists:

sh if [ $(grep -c “^\[old/]$” file) -gt 0 ]; then echo “${blob}” | grep “^device” | grep -c 1000 fi

I am sure this can be refactored but this will give you the results you want.

0

You can look for device: 1000 after having removed everything after [old]:

if sed '/^\[old\]/q' < file | grep -q 'device: 1000'; then
  echo OK
fi

With GNU sed (which you seem to be using given the GNU-specific 0,/.../ in your approach).

if sed -n '/device: 1000/q; /^\[old\]/Q1' < file; then
  echo OK
fi

(q, standard form of Q0 exits with a 0 (success) exit status while Q1 exits with exit status 1 (non-zero, so not success)).

With standard sed, you can't change sed's exit status, but you could rely on whether it outputs something:

if [ -n "$(sed -n '/^\[old\]/q;/device: 1000/!d;=;q' < file)" ]; then
  echo OK
fi

(where = outputs the line number where the first occurrence of device: 1000 is seen).

Or you could use awk which can set the exit status portably:

if awk '$0 == "[old]" {exit 1}; /device: 1000/ {exit 0}' < file; then
  echo OK
fi

You must log in to answer this question.