[英]Using AWK and setting results to bash variables/arrays?
我有一個文件可以復制mySQL的show processlist命令的結果。 該文件如下所示:
*************************** 1. row ***************************
Id: 1
User: system user
Host:
db: NULL
Command: Connect
Time: 1030455
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 2
User: system user
Host:
db: NULL
Command: Connect
Time: 1004
State: Has read all relay log; waiting for the slave
I/O thread to update it
Info: NULL
而且在相同的結構中它還會繼續運行幾次。
我想使用AWK僅獲取以下參數:時間,ID,命令和狀態,並將這些參數中的每一個存儲到不同的變量或數組中,以便以后可以在bash shell中使用/打印它們。
問題是,我對AWK非常不滿意,我不知道如何既要從文件中分離所需的參數,又如何將其設置為bash變量或數組。
預先非常感謝您的幫助!
編輯:這是到目前為止我的代碼
echo "Enter age"
read age
cat data | awk 'BEGIN{ RS="row"
FS="\n"
OFS="\n"}
{ print $2,$7}
' | awk 'BEGIN{ RS="Id"}
{if ($4 > $age){print $2}}'
文件“數據”包含類似於我上面粘貼的塊。 如果輸入的“年齡”小於數據文件中的“時間”參數(在我的awk代碼中為$ 4),則該代碼應返回ID參數,但不返回任何內容。
如果刪除if語句並打印$ 4而不是$ 2,這是我的輸出
Enter age
1
1030455
1004
2144
2086
0
所以我在想,也許空白行會以某種方式弄亂我的AWK打印件? 有一種簡單的方法可以在保留其他數據的同時忽略該空白行嗎?
這是您使用awk在輸入的每個“行”塊的每一行上,以所需的值作為一組制表符分隔的字段集的方式:
$ cat tst.awk
BEGIN {
RS="[*]+ [[:digit:]]+[]. row [*]+\n"
FS="\n"
OFS="\t"
}
NR>1 {
sub(/\n$/,"") # remove the trailing newline
gsub(/\n\s+/," ") # compress all multi-line fields into single lines
gsub(OFS," ") # ensure the only OFS in the output IS between fields
delete n2v
for (i=1; i<=NF; i++) {
name = gensub(/:.*/,"","",$i)
value = gensub(/^[^:]+:\s+/,"","",$i)
n2v[name] = value
}
if (n2v["Time"]+0 > age) { # force a numeric comparison
print n2v["Time"], n2v["Id"], n2v["Command"], n2v["State"]
}
}
$ awk -v age=2000 -f tst.awk file
1030455 1 Connect Waiting for master to send event
如果目標年齡已經存儲在shell變量中,只需從同名的shell變量中初始化awk變量即可:
$ age="2000"
$ awk -v age="$age" -f tst.awk file
上面的代碼將GNU awk用於多字符RS
(您已經擁有), gensub()
, \\s
和delete array
。
當您說“並將每個參數中的每一個存儲到不同的變量或數組中”時,這可能意味着以下幾件事之一,因此我將把這一部分留給您,但您可能正在尋找類似的東西:
arr=( $(awk '...') )
要么
awk '...' |
while IFS="\t" read -r Time Id Command State
do
<do something with those 4 vars>
done
但是到目前為止,最有可能的情況是您根本不想使用shell,而只是呆在awk中。
請記住-每次在shell中編寫循環來操縱文本時,您都會使用錯誤的方法。 UNIX shell是一個可以從其中調用UNIX工具的環境,並且用於常規文本操作的UNIX工具是awk
。
在您編輯問題以向我們詳細說明問題之前,從現在開始我們無法猜測正確的解決方案是什么。
在第一級,您具有用於運行任何其他子進程的shell。 從子進程中修改父級環境是不可能的。 當您運行bash腳本文件(右+x
)時,它將作為新進程(子進程)生成。 它可以設置自己的環境,但是當它結束運行時,您會回到原始的(父級)。
您可以在bash上設置一些變量,並將其export
到其環境中。 它會被孩子繼承。 但是,不能以相反的方向進行操作(父級不能從其子級繼承)。
如果你想從腳本文件在當前bash的上下文中執行一些命令,您可以source
腳本文件。 source ./your_script.sh
或. ./your_script.sh
. ./your_script.sh
將為您做到這一點。
如果您需要運行awk
為您過濾一些數據並將結果保存在bash中,則可以執行以下操作:
awk ... | read foo
這是因為read
是shell內置函數,而不是外部進程(檢查type read
, help
, help read
, man bash
自己檢查)。
要么:
foo=`awk ....`
您可以使用許多其他構造。 無論您使用哪種bash腳本,都請將您的代碼與bash陷阱網頁進行比較。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.