Issue
I have a two-line "keyword=keyvalue" line pattern (selectively excised from systemd/networkd.conf
file):
DNS=0.0.0.0
DNS=
and need the following 2-line answer:
0.0.0.0
But all attempts using sed
or awk
resulted in omitting the newline if the last line pattern matching resulted in an empty match.
EDIT: Oh, one last thing, this multiline-follow-cut result has to be stored back into a bash variable containing this same 'last blank-line" as well, so this is a two-step operation of preserving last-blank-line
- multiline prepending-cut-out before (or save content after) the equal
=
symbol while preserving a newline ... in case of an empty result (this is the key here). Or possibly jerry-rig a weak fixup to attach a new-line in case of an empty match result at the last line. - save the multi-line result back into a bash variable
sed
Approach
When performing cut up to and include that matched character in bash shell, the sed
will remove any blank lines having an empty pattern match:
raw="DNS=0.0.0.0
DNS=
"
rawp="$(printf "%s\n" "$raw")"
kvs="$(echo "$rawp"| sed -e '/^[^=]*=/s///')"
echo "result: '${kvs}'"
gives the result:
0.0.0.0
without the corresponding blank line.
awk
Approach
Awk has the same problem:
raw="DNS=0.0.0.0
DNS=
"
rawp="$(printf "%s\n" "$raw")"
kvs="$(echo "$rawp"| awk -F '=' -v OFS="" '{$1=""; print}')"
echo "result: '${kvs}'"
gives the same answer (it removed the blank line).
Please Advise
Somehow, I need the following answer:
0.0.0.0
in form of a two-line output containing 0.0.0.0
and a blank line.
Other Observations Made
I also noticed that if I provided a 3-line data as followed (two with a keyvalue and middle one without a keyvalue:
DNS=0.0.0.0
DNS=
DNS=999.999.999.999
Both sed
and awk
provided the correct answer:
0.0.0.0
999.999.999.999
Weird, uh?
The above regex (both sed
and awk
) works for:
- a one-line with its keyvalue,
- any-line provided that any lines have its non-empty keyvalue, BUT
- last line MUST have a keyvalue.
Just doesn't work when the last-line has an empty keyvalue.
:-/
Solution
You can use this awk
:
raw="DNS=0.0.0.0
DNS=
"
awk -F= 'NF == 2 {print $2}' <<< "$raw"
0.0.0.0
Following cut
should also work:
cut -d= -f2 <<< "${raw%$'\n'}"
0.0.0.0
To store output including trailing line breaks use read
with process substitution:
IFS= read -rd '' kvs < <(awk -F= 'NF == 2 {print $2}' <<< "$raw")
declare -p kvs
declare -- s="0.0.0.0
"
Answered By - anubhava Answer Checked By - Candace Johnson (WPSolving Volunteer)