簡體   English   中英

使用AWK並將結果設置為bash變量/數組?

[英]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()\\sdelete 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 readhelphelp readman bash自己檢查)。

要么:

foo=`awk ....`

您可以使用許多其他構造。 無論您使用哪種bash腳本,都請將您的代碼與bash陷阱網頁進行比較。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM