當前位置:
首頁 > 知識 > 8 個有力的 Awk 內建變數

8 個有力的 Awk 內建變數

Awk 有幾個非常強力的內置變數.通常來說,分為兩種類型的內置變數: - 第一種是定義的變數可以改變, 比如欄位分隔(FS)與記錄分隔(RS) - 第二種是可以用來數據處理或者數據總結,比如記錄數(NR)與欄位數目(NF) 文中 介紹了: FS,OFS, RS, ORS, NR, NR, FNR

FS: 輸入欄位分隔符變數

FS(Field Separator) 讀取並解析輸入文件中的每一行時,默認按照空格分隔為欄位變數,$1,$2...等。FS 變數被用來設置每一記錄的欄位分隔符號。FS 可以是任意的字元串或者正則表達式.你可以使用下面兩種方式來聲名FS:

使用 -F 命令選項

作為設置為普通變數使用

語法:
$ awk -F "FS" "commands" inputfilename
或者
$ awk "BEGIN{FS="FS";}"

FS 可以是任意字元或者正則表達式

FS 可以多次改變, 不過會保持不變直到被明確修改。不過如果想要改變欄位分隔符, 最好是在讀入文本之前就改變 FS, 這樣改變才會在你讀入的文本生效。

下面是一個使用 FS 讀取 /etc/passwd 以 : 作為分隔符的例子

$ cat etc_passwd.awk
BEGIN{
FS=":";
print "Name UserID GroupID HomeDirectory";
}
{
print $1" "$3" "$4" "$6;
}
END {
print NR,"Records Processed";
}

使用結果:

$ awk -f etc_passwd.awk /etc/passwd
Name UserID GroupID HomeDirectory
gnats 41 41 /var/lib/gnats
libuuid 100 101 /var/lib/libuuid
syslog 101 102 /home/syslog
hplip 103 7 /var/run/hplip
avahi 105 111 /var/run/avahi-daemon
saned 110 116 /home/saned
pulse 111 117 /var/run/pulse
gdm 112 119 /var/lib/gdm
8 Records Processed

OFS: 輸出欄位分隔符變數

OFS(Output Field Separator) 相當與輸出上的 FS, 默認是以一個空格字元作為輸出分隔符的,下面是一個 OFS 的例子:

$ awk -F":" "{print $3,$4;}" /etc/passwd
41 41
100 101
101 102
103 7
105 111
110 116
111 117
112 119

注意命令中的 print 語句的, 表示的使用一個空格連接兩個參數,也就是默認的OFS的值。因此 OFS 可以像下面那樣插入到輸出的欄位之間:

$ awk -F":" "BEGIN{OFS="=";} {print $3,$4;}" /etc/passwd
41=41
100=101
101=102
103=7
105=111
110=116
111=117
112=11

RS: 記錄分隔符

RS(Record Separator)定義了一行記錄。讀取文件時,默認將一行作為一條記錄。 下面的例子以 student.txt 作為輸入文件,記錄之間用兩行空行分隔,並且每條記錄的每個欄位用一個換行符分隔:

$ cat student.txt
Jones
2143
78
84
77
Gondrol
2321
56
58
45
RinRao
2122
38
37
65
Edwin
2537
78
67
45
Dayan
2415
30
47
20

然後下面的腳本就會從student.txt輸出兩項內容:

$ cat student.awk
BEGIN {
RS="

";
FS="
";
}
{
print $1,$2;
}
$ awk -f student.awk student.txt
Jones 2143
Gondrol 2321
RinRao 2122
Edwin 2537
Dayan 2415

在 student.awk 中,把每個學生的詳細信息作為一條記錄, 這是因為RS(記錄分隔符)是被設置為兩個換行符。並且因為 FS (欄位分隔符)是一個換行符,所以一行就是一個欄位。

ORS: 輸出記錄分隔符變數

ORS(Output Record Separator)顧名思義就相當與輸出的 RS。 每條記錄在輸出時候會用分隔符隔開,看下面的 ORS的例子:

$ awk "BEGIN{ORS="=";} {print;}" student-marks
Jones 2143 78 84 77=Gondrol 2321 56 58 45=RinRao 2122 38 37 65=Edwin 2537 78 67 45=Dayan 2415 30 47 20=

上面的腳本,輸入文件的每條記錄被 = 分隔開。 附:student-marks 便是上面的輸出.

NR: 記錄數變數

NR(Number of Record) 表示的是已經處理過的總記錄數目,或者說行號(不一定是一個文件,可能是多個)。下面的例子,NR 表示行號,在 END 部分,NR 就是文件中的所有記錄數目。

$ awk "{print "Processing Record - ",NR;}END {print NR, "Students Records are processed";}" student-marks
Processing Record - 1
Processing Record - 2
Processing Record - 3
Processing Record - 4
Processing Record - 5
5 Students Records are processed

NF:一條記錄的記錄數目

NF(Number for Field)表示的是,一條記錄的欄位的數目. 它在判斷某條記錄是否所有欄位都存在時非常有用。 讓我們觀察 student-mark 文件如下:

$ cat student-marks
Jones 2143 78 84 77
Gondrol 2321 56 58 45
RinRao 2122 38 37
Edwin 2537 78 67 45
Dayan 2415 30 47

接著下面的Awk程序,列印了記錄數(NR),以及該記錄的欄位數目: 因此可以非常容易的發現那些數據丟失了。

$ awk "{print NR,"->",NF}" student-marks
1 -> 5
2 -> 5
3 -> 4
4 -> 5
5 -> 4

FILENAME: 當前輸入文件的名字

FILENAME 表示當前正在輸入的文件的名字。 AWK 可以接受讀取很多個文件去處理。看下面的例子:

$ awk "{print FILENAME}" student-marks
student-marks
student-marks
student-marks
student-marks
student-marks

在輸入的文件的每一條記錄都會輸出該名字。

FNR: 當前輸入文件的記錄數目

當awk讀取多個文件時,NR 代表的是當前輸入所有文件的全部記錄數,而 FNR 則是當前文件的記錄數。如下面的例子:

$ awk "{print FILENAME, "FNR= ", FNR," NR= ", NR}" student-marks bookdetails
student-marks FNR= 1 NR= 1
student-marks FNR= 2 NR= 2
student-marks FNR= 3 NR= 3
student-marks FNR= 4 NR= 4
student-marks FNR= 5 NR= 5
bookdetails FNR= 1 NR= 6
bookdetails FNR= 2 NR= 7
bookdetails FNR= 3 NR= 8
bookdetails FNR= 4 NR= 9
bookdetails FNR= 5 NR= 10

附: bookdetails 與 student-marks 內容一樣,作例子. 可以看出來 NRFNR 的區別。

經常使用 NRFNR 結合來處理兩個文件,比如有兩個文件:

$ cat a.txt
李四|000002
張三|000001
王五|000003
趙六|000004
$ cat b.txt
000001|10
000001|20
000002|30
000002|15
000002|45
000003|40
000003|25
000004|60

如果想作對應的話, 比如張三|000001|10

$ awk -F "|" "NR == FNR{a[$2]=$1;} NR>FNR {print a[$1],"|", $0}" a.txt b.txt
張三 | 000001|10
張三 | 000001|20
李四 | 000002|30
李四 | 000002|15
李四 | 000002|45
王五 | 000003|40
王五 | 000003|25
趙六 | 000004|60

8 個有力的 Awk 內建變數

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 程序員小新人學習 的精彩文章:

Nginx代理webSocket經常中斷的解決方案,如何保持長連接
C語言字元串相關函數實現

TAG:程序員小新人學習 |