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

标签 bash awk sed

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

DNS=0.0.0.0
DNS=

并且需要以下两行答案:

0.0.0.0

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

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

  1. 在等于 = 符号之前进行多行预置剪切(或在之后保存内容),同时保留换行符...以防结果为空(这是此处的关键)。或者可能会偷工减料,在最后一行匹配结果为空的情况下附加一个换行符。
  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="" '{$1=""; 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)适用于:

  • 一行及其键值,
  • any-line 前提是任何行都有其非空键值,但是
  • 最后一行必须有一个键值。

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

:-/

最佳答案

您可以使用此awk:

raw="DNS=0.0.0.0
DNS=
"

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

以下剪切也应该有效:

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


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

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

declare -p kvs
declare -- s="0.0.0.0

"

Code Demo:

关于bash - 剪切粘贴,同时保留空匹配的最后一个空白行(awk 或 sed),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71370206/

相关文章:

sed - 从多个文件中删除多行文本

string - bash 中 ${#} 背后的故事是什么

linux - 是否可以查看正在运行但已修改的 bash 脚本的原始内容?

linux - 将位置参数给出的文件中的所有数字相加

regex - Notepad++ - 如何将字符添加到行首

linux - 将目录中每个文件的标签之间的文件内容提取到新位置

linux - 每隔 x(毫秒)暂停一个 shell 脚本以减少立即的 CPU 使用率

bash - shell脚本中的性能问题

awk - sed 匹配模式并打印模式前的两行以及直到文件末尾的所有行

linux - 基于循环模式和行数的日志拆分