試試這個:
awk -F'= *' '/parameter1/ {
if (++numUnit % 3 == 1) {par1 += $2}
else if (numUnit % 3 == 2) {par2 += $2}
else {par3 += $2}
}
END {print "numUnitsA parameter1=" par1
print "numUnitsA parameter1=" par2
print "numUnitsA parameter1=" par3}' "$filename"
無循環的真正原因。這會將文件作爲參數並查找「numUnitX」的出現次數,獲取下一行並將該值添加到與X相對應的總值中。最後,它將打印總計。
替代答案:
$ cols=$(($(grep parameter1 $filename | wc -l)/3))
$ grep parameter1 "$filename" | sed 's/.*= //' | pr -ts"+" --columns "$cols" | bc
這將得到的所有值,然後粘貼單元A,B和C值彼此相鄰在不同的行,由一個「+」分離,並計算出總和使用bc
。輸出是三行,分別包含單位A,B和C的總數。
更新 回答現在只要參數不緊跟numUnits
標籤。
說明
AWK是把一個文件分成記錄(將它們看作行,即使他們可以多行)和字段(想到這些欄目,與前一個程序評論仍然有效)。這些記錄和字段的分隔可以由用戶定義,但默認分隔符是記錄的換行符和字段的選項卡。因此,文件結構的定義如下:
record1: field1 field2 spaces allowed field 3
record2: this record has only one field
record4: the previous line was an empty record
record5: in awk you can refer to fields using $1, $2, $3. like this:
$1 in your code means this field $2 in code this field $3 $4
record7: $0 is the variable for the entire record!
的字段可以使用$1
,$2
等加以解決,特殊$0
是指整個記錄。兩個簡單的例子來說明。首先我們打印整個文件,渲染腳本相當於cat
:awk '{print} file' or
awk'{print $ 0}'文件. A second example changes every record (i.e. line as default) to the literal string
不模擬awk :
awk'{$ 0 =「don'\」'mock awk「}'文件. Note the special care to output a
' 。
Builtins一些強大的awk內建變量可供我們使用,有些將在下面解釋。
FS
字段分隔符,默認FS = "\t"
RS
記錄分隔符,默認RS = "\n"
OFS
輸出字段分隔符,默認OFS = " "
ORS
輸出記錄分隔符,默認ORS = "\n"
NR
當前記錄數,最後這是文件中的記錄數。
NF
此記錄中的字段數。
FILENAME
正在處理的文件的文件名。
這些是非常有用的變量,當打印輸出字段分隔符OFS
時會自動插入。下面的示例代碼打印第一行的前兩個字段,由一個空格分隔(OFS
通過使用空格插入)。 awk 'NR == 1 {print $1, $2}' file
。
結構基本AWK結構如下:
awk -F'= ' '
# this is a comment (starting with #)
# begin clause
BEGIN {
# do stuff BEFORE parsing the file
FS = "= +" # this is also achieved using the -F flag above
...
}
/some regex/ {
# code here will be executed if record contains 'some regex'
# example: count number of lines that match this regex
count++ # increment count with one
}
NR == 1 {
# code here will only be executed on the first record
}
{
# code right here will always be executed (i.e. for every record)
# note the regex is missing => match every record
...
}
# add more clauses to match certain records before the end clause:
END {
# execute code AFTER all files (you can read multiple files) have been parsed
print count # print number of records containing our regex
}' path/to/some/file_to_parse /another/path/to/another/file
基本上代碼包裹在大括號如果前面,則返回true,則執行它是否是一個正則表達式被在記錄(/regex notation/
)找到或一個邏輯比較。當條件不足時,代碼將始終執行。
解決方案代碼分析
正如你看到的,我們沒有一個BEGIN條款,只有一個記錄條款。我們正在尋找記錄,在我們的案例中,包含字符串'parameter1'的行。這些正是包含我們想要總結的值的行。
我們將字段分隔符設置爲正則表達式= +
表示等號和一個或多個空格。請注意,我們感興趣的記錄,這意味着我們有兩個記錄:
paramter1 = 4
field1 |||field 2,
這意味着$2
現指4
。請注意,$2
在以下記錄中將爲空:paramter1=4
,因爲等號後沒有空格。
現在我們有箱子的開關:等效
numUnit
相當於1個模3
numUnit
被2模3
numUnit
相當於3模3.
請注意,我們首先有if (++numUnit ...
,這會在評估表達式之前增加變量numUnit
(所以在if檢查條件之前)。正如你所看到的,awk不是強類型的,所以不需要先聲明numUnit
。在第一次增加時,awk會假設它是零,因爲你試圖添加一些東西,而他不知道它是什麼。
因此numUnit
每增加一次,我們就會找到一條包含paramter1
的記錄。由於第一次將numUnit
評估爲1,然後遵循模式1 2 0 1 2 0 ...'和'nunUnit'模式爲numUnitA numUnitB numUnitC numUnitA numUnitB ...
,您可以看到每個這些案例都處理一種類型的所有記錄。每個案例現在都會將參數的值添加到它的總數中(正如您現在可以在代碼中輕鬆查看的那樣)。
最後,我們通過打印出信息來結束awk腳本,請記住,只有在所有記錄被讀取後纔會執行一次。這應該很清楚。
我強烈建議閱讀awk,它是一種非常強大的腳本語言,允許許多高級編程語言的構造。起初可能看起來很難,但這完全值得!
縮進你的代碼。 – gsamaras