我想使用 awk 从文件中提取文本,它基本上可以正常工作,但我想使用变量来查找模式使其变得动态。
它应该如何工作:
文件 test_input 包含(顺便说一句:从 HP DP omnimm -show_locked_devs
中提取)
Type: Device
Name/Id: Drive1
Pid: 28405
Host: Host1
Type: Cartridge
Name/Id: Lib1
Pid: 28405
Host: Host1
Location: 47
...
- 获取 Drive1 的“Pid”编号 => 命令查找模式 (Drive1) 并显示文件 test_input (28405) 中的下一行
cat test_input | awk 'c&&!--c;/Drive1/{c=1}'| awk '{打印$2}'
28405
- 获取“Location”编号 => 查找所有“Pid”编号并显示每个匹配项的下 2 行(记录),然后使用 grep 从输出中过滤“Location”并显示第二个字段 (47)
cat test_input | awk 'c&&!--c;/28405/{c=2;打印 $0}'| grep 位置 | awk '{打印$2}'
47
我注意到 AWK 中的双引号可以处理 SHELL 变量,但是当我在脚本中使用 SAME 命令时,我收到错误消息“awk:无法正确解析语句。”
DRIVE=Drive1;cat test_input | awk "c&&!--c;/$DRIVE/{c=1}"| awk '{打印$2}'
28405
如果您有一些如何从 SHELL 获取工作变量的提示,请告诉我。 我也知道我的命令和重定向可能很复杂,但是我不是脚本大师:)
最佳答案
如果您只需要使用环境变量,那么您可以使用ENVIRON
awk内置哈希。如果您想将参数传递给 awk ,您可以使用 -v
选项。
两者的示例:
cat >inputfile <<EOT
aaa
bbbxxx
xxxccc
ddd
EOT
VAR=xxx
awk -vVAR="$VAR" '$0~VAR {print ENVIRON["USER"]":"$0}' inputfile
我添加了示例输入文件
的创建。
据我所知,一些awk版本 -v
和 VAR
之间需要空格。
如果我建议您在整个脚本行中使用 '
而不是 "
。如果您使用大量 awk ,它会让生活变得更轻松。 .
输出:
myuser:bbbxxx
myuser:xxxccc
如果我理解得很好,您需要收集非“设备” block 中所有设备和所有位置的名称。我假设时钟以标签 Type
开头,并且标签顺序始终相同。如果没有,请。通知我。基于这些假设,我的代码如下所示:
awk '$1=="Type:"{dev=$2=="Device"}
dev && $1=="Name/Id:"{name=$2}
dev && $1=="Pid:"{pids[name]=$2}
!dev && $1=="Pid:"{pid=$2}
!dev && $1=="Location:"{locs[pid]=$2}
END {
for(i in pids) {
pid = pids[i];
print i"\t"(pid in locs ? locs[pid] : "None");
}
}
' inputfile
它填充 pids
和 locs
哈希,然后打印在 pids
哈希中找到的所有设备名称,并且位置属于此pid(如果找到)。
输出:
Drive1 47
当然,如果位置始终位于设备 block 之后,则可以在找到位置后立即打印该行。因此END
部分可以被删除。
关于shell - AWK - 从 SHELL 到模式的输入变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26775952/