AWK-从SHELL到模式的输入变量

AWK-从SHELL到模式的输入变量,shell,variables,awk,scripting,Shell,Variables,Awk,Scripting,我想使用awk从文件中提取文本,它基本上可以正常工作,但我想使用变量来寻找模式 工作原理: 文件测试输入包含(顺便说一句:从HP DP提取omnimm-显示锁定的开发者) 获取Drive1=>命令查找模式(Drive1)的“Pid”编号,并显示文件test_输入(28405)的下一行 cat测试|输入| awk'c&&--c/Drive1/{c=1}'| awk'{print$2}' 28405 获取“位置”编号=>找到所有“Pid”编号并显示每个匹配的下2行(记录),然后使用grep从输

我想使用awk从文件中提取文本,它基本上可以正常工作,但我想使用变量来寻找模式

工作原理:

文件测试输入包含(顺便说一句:从HP DP提取omnimm-显示锁定的开发者)

  • 获取Drive1=>命令查找模式(Drive1)的“Pid”编号,并显示文件test_输入(28405)的下一行
cat测试|输入| awk'c&&--c/Drive1/{c=1}'| awk'{print$2}'
28405

  • 获取“位置”编号=>找到所有“Pid”编号并显示每个匹配的下2行(记录),然后使用grep从输出中筛选“位置”,并显示第2个字段(47)
cat测试|输入| awk'c&&--c/28405/{c=2;print$0}'| grep Location | awk'{print$2}'
47

我注意到AWK中的双引号可以处理SHELL变量,但是当我在脚本中使用相同的命令时,我得到了错误消息“AWK:语句无法正确解析”

DRIVE=Drive1;cat测试输入| awk“c&&!-c;/$DRIVE/{c=1}”| awk'{print$2}'
28405

如果您有一些关于如何从SHELL获取工作变量的提示,请告诉我。
另外,我知道我的命令和重定向可能很复杂,但我不是脚本大师:)

如果您只需要使用环境变量,那么您可以使用
环境
内置哈希。如果要将参数传递给,可以使用
-v
选项

这两方面的一个例子是:

cat >inputfile <<EOT
aaa
bbbxxx
xxxccc
ddd
EOT

VAR=xxx
awk -vVAR="$VAR" '$0~VAR {print ENVIRON["USER"]":"$0}' inputfile
如果我理解得很好,您需要收集非“设备”块中所有设备和所有位置的名称。我假设时钟从标签
类型开始,标签顺序总是相同的。如果没有,请。告诉我。基于这些假设,我的代码如下所示:

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

当然,如果该位置始终位于设备块之后,则在找到该位置时可以立即打印该行。因此可以删除
结束部分。

不清楚您想要什么,但可能是:

$ cat tst.awk
BEGIN{ RS=""; FS="[:[:space:]]+" }
{
    for (i=1;i<=NF;i+=2)
       name2val[$i] = $(i+1)
}   
(name2val[key] == val) && (tgt in name2val) {
    print name2val[tgt]
}
$
$ awk -v key="Name/Id" -v val="Drive1" -v tgt="Pid" -f tst.awk file
28405
$
$ awk -v key="Pid" -v val="28405" -v tgt="Location" -f tst.awk file
47
$cat tst.awk
开始{RS=”“;FS=“[:[:空格:]+”}
{

对于(i=1;IPL。不要使用
cat文件| awk…
,应该是
awk''文件
。而且在管道中使用几个
awk
grep
通常可以简化为一个
awk
。似乎是这样的:@Jidder:你的建议中至少少了一个笑脸!)只对变量进行双引号引用,其他所有内容保持单引号引用。例如:
awk'c&&!-c;/“$DRIVE”/{c=1}'
这里有大约1e3个关于将变量传递给awk的问题。请进行搜索。。。
Drive1  47
$ cat tst.awk
BEGIN{ RS=""; FS="[:[:space:]]+" }
{
    for (i=1;i<=NF;i+=2)
       name2val[$i] = $(i+1)
}   
(name2val[key] == val) && (tgt in name2val) {
    print name2val[tgt]
}
$
$ awk -v key="Name/Id" -v val="Drive1" -v tgt="Pid" -f tst.awk file
28405
$
$ awk -v key="Pid" -v val="28405" -v tgt="Location" -f tst.awk file
47