我有一个 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