简体   繁体   English

BASH:grep / awk / sed提取可变数据

[英]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 builtins: 我看到你想要一个grep / awk / sed答案,但你可能有兴趣知道你需要的东西纯粹是用内置的:

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-LTDOMAIN行中的一个。

Note associative arrays require 4.0 or more. 注意关联数组需要 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM