[英]BASH: grep/awk/sed to extract variable data
UPDATE I need to clarify that Jon8RFC-LT and DOMAIN are also just generic examples of dynamic content, like the IP address and MAC address; 更新我需要澄清Jon8RFC-LT和DOMAIN也只是动态内容的通用示例,如IP地址和MAC地址; nmblookup retrieves and displays entirely dynamic content based on the ip address.
nmblookup根据ip地址检索并显示完全动态内容。 If awk is used, I need to have a way to pull 4 dynamic values from the nmblookup: IP, hostname/asset name, domain name, MAC address.
如果使用awk,我需要有一种方法从nmblookup中提取4个动态值:IP,主机名/资产名称,域名,MAC地址。 Sorry for the confusion, I updated the code to make it more clear.
对不起,我更新了代码以使其更清晰。
I have been searching and using my Linux book for a couple of days and cannot find what I need for awk/gawk/grep/egrep/sed (I think I need one or more of those, elegantly). 我一直在搜索和使用我的Linux书几天,找不到我需要的awk / gawk / grep / egrep / sed(我想我需要其中一个或多个,优雅)。 In a bash script, I'm running:
在bash脚本中,我正在运行:
su_nmblookup=$(nmblookup -A $ipaddress)
which returns 返回
WARNING: The "idmap backend" option is deprecated added interface eth0 ip=a07d::a07d:a07d:a07d:a07d%eth0 bcast=b57d::ffff:ffff:ffff:ffff%eth0 netmask=ffff:ffff:ffff:ffff:: added interface eth1 ip=b57d::b57d:b57d:b57d:b57d%eth1 bcast=a07d::ffff:ffff:ffff:ffff%eth1 netmask=ffff:ffff:ffff:ffff:: added interface eth0 ip=234.234.234.234 bcast=12.12.12.12 netmask=255.255.0.0 Socket opened. Looking up status of 123.123.123.123 JON8RFC-LT <00> - B <ACTIVE> DOMAIN <00> - <GROUP> B <ACTIVE> JON8RFC-LT <20> - B <ACTIVE> DOMAIN <1e> - <GROUP> B <ACTIVE> MAC Address = 4F-A2-4F-A2-4F-A2
The best I've managed, is to chop it down with this code: 我管理的最好的是用这段代码将其删除:
display=${su_nmblookup/#*Looking/\Looking}
Looking up status of 123.123.123.123 JON8RFC-LT <00> - B <ACTIVE> DOMAIN <00> - <GROUP> B <ACTIVE> JON8RFC-LT <20> - B <ACTIVE> DOMAIN <1e> - <GROUP> B <ACTIVE> MAC Address = 4F-A2-4F-A2-4F-A2
However, what I'd like to know is how to return either of these cleaned up formats. 但是,我想知道的是如何返回这些清理过的格式中的任何一种。 I want to learn how the grep/awk/sed works with extracting data with these two examples, one with preserving the formatting, and one with just new lines.
我想了解grep / awk / sed如何使用这两个示例提取数据,一个保留格式,另一个只保留新行。 I had a hell of a time even getting the quoting/coding to work properly here because of the formatting and gt/lt symbols!
由于格式化和gt / lt符号,我有一段时间甚至让引用/编码在这里正常工作!
Looking up status of 123.123.123.123 JON8RFC-LT DOMAIN 4F-A2-4F-A2-4F-A2
OR, simply 或者,简单地说
JON8RFC-LT DOMAIN 123.123.123.123 4F-A2-4F-A2-4F-A2
Thank you for your help! 谢谢您的帮助!
Assuming the output of nmblookup -A 123.123.123.123
is redirected to file input.txt
假设
nmblookup -A 123.123.123.123
的输出被重定向到文件input.txt
awk '/Looking up status of/ {print} /JON8RFC-LT/ {if(a!=1){print "\t"$1;a=1}} /DOMAIN/ {if(b!=1){print "\t"$1;b=1}} /MAC Address/ {print "\t"$4}' input.txt
Updated as Etan Reisner suggested to be shorter: 更新为Etan Reisner建议更短:
awk '/Looking up status of/ {print} /JON8RFC-LT/ && !a {print "\t"$1;a=1} /DOMAIN/ && !b {print "\t"$1;b=1} /MAC Address/ {print "\t"$4}' input.txt
output: 输出:
Looking up status of 123.123.123.123
JON8RFC-LT
DOMAIN
4F-A2-4F-A2-4F-A2
Updated for Dynamic content 更新了动态内容
awk '/Looking up status of/,/MAC Address/ {print; getline;print "\t"$1;getline;print "\t"$1;getline;getline;getline;getline;print "\t"$4;exit 0}' input.txt
Assumes on the two lines after line Looking up ...
you want the first word. 假设在线后面两行
Looking up ...
你想要第一个单词。 Then ignores three lines and then prints MAC address. 然后忽略三行,然后打印MAC地址。
I see you want a grep
/ awk
/ sed
answer, but you may be interested to know what you need is possible purely with bash builtins: 我看到你想要一个
grep
/ awk
/ sed
答案,但你可能有兴趣知道你需要的东西纯粹是用bash内置的:
unset results
declare -A results
while read; do
case $REPLY in
*'Looking up status of '*) ip="${REPLY##* }";;
*'MAC Address = '*) mac="${REPLY##* }";;
*' '*) tmp="${REPLY# }"; results[${tmp%% *}]=1 ;;
esac
done < <(nmblookup -A $ipaddress)
printf "%s\n" ${!results[@]}
echo $ip
echo $mac
This script fragment may be placed in your existing script. 此脚本片段可以放在现有脚本中。
This script reads each line of input and applies a case
switch to match the patterns you are interested in. Each pattern has its own set of commands to format the data you need. 此脚本读取每行输入并应用
case
开关以匹配您感兴趣的模式。每个模式都有自己的一组命令来格式化您需要的数据。 In the case of lines that begin with 4 spaces, we use a bash associative array to make sure we only get one of each of the JON8RFC-LT
and DOMAIN
lines. 对于以4个空格开头的行,我们使用bash关联数组来确保我们只得到每个
JON8RFC-LT
和DOMAIN
行中的一个。
Note associative arrays require bash 4.0 or more. 注意关联数组需要bash 4.0或更高版本。
An annotated awk
solution that provides both output formats - prettied and raw - selectable by a variable: 带注释的
awk
解决方案 ,提供输出格式 - 漂亮和原始 - 可由变量选择:
# Set this to:
# * 1 for a "pretty" display with header line and indentation
# * 0 for printing the raw data items only.
pretty=1
awk -v pretty=$pretty '
# Skip lines before "Looking up ..."
!startRow && /Looking up status of / { startRow=NR; }
!startRow { next }
# Parse the lines of interest relative to the "Looking up ..." row.
NR==startRow { ip=$5; header=$0; next } # IP address
NR==startRow+1 { nm=$1; next } # name, e.g.: "JON8RFC-LT"
NR==startRow+2 { dm=$1; next } # domain, e.g.: "DOMAIN"
/MAC Address =/ { ma=$4; exit } # MAC address, e.g.: "4F-A2-4F-A2-4F-A2"
END { # all relevant lines processed; output result
if (pretty) # print with header and indentation
{ print header; print "\t" nm; print "\t" dm; print "\t" ma }
else # print raw data items only
{ print nm; print dm; print ip; print ma }
}' <(nmblookup -A $ipaddress)
A few quick pointers: 一些快速指示:
-v pretty=$pretty
defines an awk
variable based on a shell variable; -v pretty=$pretty
基于shell变量定义awk
变量; note how the awk
program as a whole is enclosed in single quotes to prevent accidental shell expansions inside the awk
program, which should be treated as its own world, separate from the shell. awk
程序如何用单引号括起来,以防止在awk
程序中意外的shell扩展,这应该被视为它自己的世界,与shell分开。 !startRow
: awk
variables in a numeric/Boolean context default to 0
/ false
if not yet defined, so this expression evaluates to false
until startRow
is set to a non-zero value. !startRow
:如果尚未定义,则数字/布尔上下文中的awk
变量默认为0
/ false
,因此在将startRow
设置为非零值之前,此表达式的计算结果为false
。 /Looking up status of/
is a regex that is matched against the current input line; /Looking up status of/
是与当前输入行匹配的正则表达式; NR
contains the current, 1-based row (line) number. NR
包含当前的基于1的行(行)编号。 next
skips remaining pattern/actions for the current line and proceeds to the next line. next
跳过当前行的剩余模式/操作并继续下一行。 NR==startRow
is a pattern that evaluates to true if the current line's index matches the value stored in startRow
NR==startRow
是一种模式,如果当前行的索引与startRow
存储的值匹配,则该模式为true $1
, for instance, represents the 1st field from the current line - by default, awk
breaks lines into fields - starting with index 1 and the ending index stored in variable NF
- based on whitespace. $1
表示当前行的第一个字段 - 默认情况下, awk
将行分为字段 - 从索引1开始,结束索引存储在变量NF
- 基于空格。 END
is a special pattern whose associated block is executed after all input lines have been processed; END
是一种特殊模式,其关联块在处理END
所有输入行后执行; note that an exit
command in a previous action still causes the END
action to be processed. exit
命令仍会导致处理END
操作。 <(...)
is an instance of process substitution which provides the output from any command as a pseudo file. <(...)
是进程替换的一个实例,它将任何命令的输出提供为伪文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.