grep 设备名称并查找下一个值:

grep 设备名称并查找下一个值:

我有一个 find 命令的输出:

abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23

其中 abc、def 和 geh 是设备名称,可以是任意长度,其他是属于设备的 IP 地址。就像abc,10.11.13.14设备一样abc。 IP 应位于逗号分隔符旁边。

当我 grep 查找设备名称时,如何使用 sed、grep 或 awk 打印关联的 IP?简而言之,我希望 IP 显示在设备名称旁边。

答案1

我对 awk 更熟悉,所以我想在 awk 中提出两个解决方案。

解决方案1

$ echo abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23 | awk -F, '{for (i=1; i<NF; i+=2) if ($i == "def") print $(i+1)}'
1.2.3.4

在本例中,我正在寻找机器名称“def”,如果找到,则打印下一列。

解决方案2

$ echo abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23 | tr , \\n | awk '/def/ {getline;print}'
1.2.3.4

在此解决方案中,我使用tr命令将逗号转换为新行,搜索“def”并打印后面的行。我希望这些解决方案对您有用。

答案2

假设您有带有 Perl 兼容正则表达式的 GNU grep:

device="def"
grep -oP '(?<=\b'"$device"',).*?(?=,|$)'

这意味着:查找一侧的“def,”和另一侧的“逗号或行尾”之间的内容

编辑:向 RE 添加字边界以更精确地查找给定设备。

答案3

除了 shell 内置命令之外,不使用任何命令:

string='abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23'
dev=def

s=,$string,
case $s in
  (*,"$dev",*) ip=${s#*",$dev,"}; ip=${ip%%,*};;
  (*) ip=unknown
esac

printf '%s\n' "$ip"

使用 zsh,可以轻松将该字符串映射到关联数组:

string='abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23'
typeset -A ip
ip=(${(s:,:)string})
print -r -- $ip[def]

答案4

[0-9\.]\{7,15\}使用 sed替换每个 IP 地址。 IP 地址由数字和点组成,位置从 7 到 15 个不等。

将每个 IP 地址替换为自身,后跟换行符\n,这基本上意味着每个设备、IP 组合都会有自己的行。

echo "abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23" | sed 's/\([0-9\.]\{7,15\}\),/\1\n/g' 
abc,10.11.13.14
def,1.2.3.4
geh,6.7.54.23


echo "abc,10.11.13.14,def,1.2.3.4,geh,6.7.54.23" | sed 's/\([0-9\.]\{7,15\}\),/\1\n/g'  | grep def
def,1.2.3.4

相关内容