2014-11-06 79 views
2

我想使用awk從文件中提取文本,它基本上可以正常工作,但我希望使用變量爲dymamical查找模式。AWK - 從SHELL模式輸入變量

應該如何工作的:

文件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 => find命令模式 「PID」 號(DRIVE1)和從文件test_input(28405)

cat test_input | awk 'c&&!--c;/Drive1/{c=1}'| awk '{print $2}' 28405

012顯示下一行
  • GET「位置」編號=>找到所有的「PID」 numberes並顯示下一個2線(記錄)對於每個匹配,則使用濾波器「位置」的grep從輸出並顯示第二字段(47)

cat test_input | awk 'c&&!--c;/28405/{c=2; print $0}'| grep Location | awk '{print $2}' 47

我注意到AWK中的雙引號可以處理SHELL變量,但是當我在腳本中使用SAME命令時,我收到錯誤消息「awk:語句無法正確解析。

DRIVE=Drive1;cat test_input | awk "c&&!--c;/$DRIVE/{c=1}" | awk '{print $2}' 28405

如果你有一些提示如何從SHELL得到工作變量,請讓我知道。 我也知道,我的命令和重定向很可能複雜,但耶我不是腳本大師:)

+3

PLS。不要使用'cat file | awk ...',應該是'awk''文件'。而且在管道中使用多個'awk'和'grep'通常可以簡化爲一個'awk'。 – TrueY 2014-11-06 09:37:36

+0

似乎是這樣的:[如何在awk腳本中使用shell變量](http://stackoverflow.com/q/19075671/1983854) – fedorqui 2014-11-06 09:39:49

+0

這樣做而不是'cat <<<「$(更多文件)」> STDOUT 1 >&2 | awk' – 2014-11-06 09:41:24

回答

2

如果你只需要使用環境變量,那麼你可以使用ENVIRON內置散列。如果您想將參數傳遞給,則可以使用-v選項。

兩個例子:

cat >inputfile <<EOT 
aaa 
bbbxxx 
xxxccc 
ddd 
EOT 

VAR=xxx 
awk -vVAR="$VAR" '$0~VAR {print ENVIRON["USER"]":"$0}' inputfile 

我加入樣品inputfile的創建。

據我所知,在某些版本中,在-vVAR之間需要空格。

如果我建議您在整個腳本行周圍使用'而不是"。如果您使用大量的,它會使生活變得更輕鬆。

輸出:

myuser:bbbxxx 
myuser:xxxccc 

如果我深知,你需要收集所有設備的名稱和位置都非「設備」模塊。我假設時鐘從標籤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 

當然,如果該位置的設備塊後總是,線路可以立即當位置發現打印。所以END部分可以被刪除。

0

目前尚不清楚你想要什麼,但也許這:

$ 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