剪切粘贴,同时为空匹配保留最后一个空白行(awk 或 sed)

Cut-n-paste while preserving last blank line for empty match (awk or sed)

我有一个两行的“keyword=keyvalue”行模式(有选择地从systemd/networkd.conf文件中删除):

DNS=0.0.0.0
DNS=

并需要以下两行答案:

0.0.0.0

但是如果最后一行模式匹配导致空匹配,所有使用 sedawk 的尝试都会导致省略换行符。

编辑: 哦,最后一件事,这个多行跟随切割结果必须存储回一个 bash 变量中,该变量也包含这个相同的“最后一个空白行”,所以这是保留最后一个的两步操作 -空行

  1. 等号 = 符号之前(或之后保存内容)的多行前置剪切,同时保留换行符...以防出现空结果(这是这里的关键)。或者可能是 jerry-rig 一个弱修复来附加一个新行,以防最后一行的匹配结果为空。
  2. 将多行结果保存回 bash 变量

sed 方法

当在 bash shell 中执行剪切并包含匹配字符时,sed 将删除具有空模式匹配的任何空行:

raw="DNS=0.0.0.0
DNS=
"
rawp="$(printf "%s\n" "$raw")"

kvs="$(echo "$rawp"| sed -e '/^[^=]*=/s///')"

echo "result: '${kvs}'"

给出结果:

0.0.0.0

没有对应的空行

awk 方法

awk有同样的问题:

raw="DNS=0.0.0.0
DNS=
"
rawp="$(printf "%s\n" "$raw")"

kvs="$(echo "$rawp"| awk -F '=' -v OFS="" '{=""; print}')"

echo "result: '${kvs}'"

给出相同的答案(它删除了空行)。

请指教

不知何故,我需要以下答案:

0.0.0.0

以包含 0.0.0.0 和一个空行的两行输出形式。

其他观察结果

我还注意到,如果我提供如下的 3 行数据(两行有键值,中间一行没有键值:

DNS=0.0.0.0
DNS=
DNS=999.999.999.999

sedawk都提供了正确答案:

0.0.0.0

999.999.999.999

奇怪,嗯?

以上正则表达式(sedawk)适用于:

当最后一行有一个空键值时就不起作用。

:-/

你可以使用这个 awk:

raw="DNS=0.0.0.0
DNS=
"

awk -F= 'NF == 2 {print }' <<< "$raw"
0.0.0.0

以下 cut 也应该有效:

cut -d= -f2 <<< "${raw%$'\n'}"
0.0.0.0


要存储包括尾随换行符的输出,请使用 read 和进程替换:

IFS= read -rd '' kvs < <(awk -F= 'NF == 2 {print }' <<< "$raw")

declare -p kvs
declare -- s="0.0.0.0

"

Code Demo: