awk知識點全回顧

来源:http://www.cnblogs.com/f-ck-need-u/archive/2017/09/12/7509812.html
-Advertisement-
Play Games

本文目錄:1.awk簡介和基本語法格式2.print和printf格式化輸出3.輸入行的欄位分隔符和行分隔符4.BGEIN和END5.數組6.流程式控制制語句 6.1 條件判斷語句 6.2 while迴圈 6.3 do迴圈 6.4 for迴圈7.更完整的awk程式格式和表達式8.awk中的變數9.awk ...


本文目錄:
1.awk簡介和基本語法格式
2.print和printf格式化輸出
3.輸入行的欄位分隔符和行分隔符
4.BGEIN和END
5.數組
6.流程式控制制語句
  6.1 條件判斷語句
  6.2 while迴圈
  6.3 do迴圈
  6.4 for迴圈
7.更完整的awk程式格式和表達式
8.awk中的變數
9.awk中的內置函數
10.自定義函數
11.getline函數
12.向awk傳遞變數

1. awk簡介和基本語法格式

Awk自動地搜索輸入文件,並把每一個輸入行切分成欄位。許多工作都是自動完成的,例如讀取每個輸入行、欄位分割、存儲管理、初始化等。在AWK中不需聲明變數數據類型,它內置字元串類型和數值類型。

一般來說,在CentOS上安裝的awk預設是gawk。它的調用格式為:

awk [OPTIONS] -f program_file [--] filename_list
awk [OPTIONS] [--] program filename_list

program是awk程式的重中之重,稱為awk的程式,它的格式為PATTERN{ACTIONS}。awk每讀入一行,都會先與PATTERN做匹配比較,當找到符合條件的數據就執行對應的ACTION。

其中PATTERN或ACTIONS二者可省一。省略PATTERN時表示對所有行都執行ACTIONS,省略ACTIONS表示對符合條件的行執行預設的print動作。因為二者可省一,所以用大括弧{}將ACTIONS部分包圍起來,以區分PATTERN和ACTIONS。

一個簡單的例子,輸出/etc/passwd中用戶shell為/bin/bash的用戶名,其中使用"-F"選項指定冒號作為分隔符。

awk -F':' '$7 == "/bin/bash"{print "who use bash shell: ",$1}' /etc/passwd

其中位置變數$1,$2...為該行的第幾個欄位,"$0"表示整行。

如果要輸出多個欄位,則欄位之間使用逗號","分隔,例如{print $1,$5}但輸出時,仍預設以空格分隔各輸出欄位。

如果action為print $1 $5,則結果會將"$1"和"$5"拼接在一起,因為空格是awk中的拼接字元。例如變數賦值name = "abc" "bcd"等價於name="abcbcd"。其實不算是拼接符,而是因為awk會忽略任何不被引號包圍的空白。

2.print和printf格式化輸出

awk使用print和printf輸出數據,不僅可以輸出到標準輸出中,還可以重定向到文件中,使用管道傳遞給另一個命令。

  1. print
    將 $0 列印到標準輸出。等價於print $0
  2. print expression, expression, …
    列印各個 expression, expression 之間由 OFS 分開, 由 ORS 終止
  3. print expression,expression,… > filename
    文件名filename必須使用雙引號包圍,否則被當作變數。且文件只會被打開一次。
  4. print expression,expression,… >> filename
  5. print expression,expression,… | command
    將數據傳遞給系統命令。命令需要使用雙引號包圍。
  6. printf(format,expression,expression,…)
  7. printf(format,expression,expression,…) > filename
  8. printf(format,expression,expression,…) >> filename
  9. printf(format,expression,expression,…) | command
  10. close(filename), close( command)
    斷開 print 與 filename (或 command) 之間的連接
  11. system(command)
    執行 command; 函數的返回值是 command 的退出狀態

如果print或printf的參數列表中含有操作符,則需要使用括弧包圍,否則容易產生歧義。如:

print($1, $3) > ($3 > 100 ? "bigpop" : "smallpop")
print $1, ($2 > $3) 

執行系統命令的方式,可以通過管道的方式,也可以通過system()函數。註意包圍命令的引號加的位置。

awk 'BEGIN{name="ma long shuai";print (1,2,3,4) | "echo " name}'
awk 'BEGIN{while (("fdisk -l" | getline) >0){print $0}}'
awk 'BEGIN{system("fdisk -l")}'
awk 'BEGIN{name="ma long shuai";system("echo " name)}'

printf命令可以輸出更格式化的數據。

printf(format, value1, value2, ... , valueN)

format是一個字元串,包含按字面輸出的純文本,還包含輸出格式,格式使用格式說明符"%"描述,後面跟著幾個字元,這些字元控制一個value的輸出格式。第一個"%"描述value1的輸出格式,第二個"%"描述value2的輸出格式,依次類推。因此,"%"的數量應該和被輸出的value數量一樣多。

例如:

{ printf("total pay for %s is $%.2f\n", $1, $2 * $3) }
{ printf("%-8s $%6.2f\n", $1, $2 * $3) }

第一個程式包含了兩個要格式化的value,分別是"$1"和"$2 * $3"。這兩個value的輸出格式分別被"%s"和"%.2f"描述,前者表示按字元串格式輸出"$1",後者表示按小數值格式輸出"$2 * $3",且小數位占2位。由於printf不自帶尾隨換行符,因此手動加一個換行符"\n"。

第二個程式,"%-8s"表示"$1"按字元串格式輸出,但短橫線"-"表示要左對齊輸出,"8"表示占用8個字元寬度,不足之數在右邊空格補齊。"%6.2f"表示按小數格式輸出"$2 * $3",且小數位占用2位,總字元數占用6位。註意,小數點也占用一個字元寬度。因此,一個可能的輸出值為"123.20"。

格式說明符"%"後可跟以下幾個常見字元:

  • 格式符:
    • %d,%i:十進位整數;
    • %f:顯示浮點數;
    • %s:顯示字元串;
    • %u:無符號整數;
    • %%:顯示%自身。
  • 修飾符:
    • N:顯示寬度;N為數值,寬度不足時若為左對齊則右邊空格補足,若右對齊則左邊空格補足。
    • -:左對齊;
    • +:顯示數值正負號。
    • 0:表示以0填充。

3.輸入行的欄位分隔符和行分隔符

使用"-F"選項或設置內置變數"FS"可以控制輸入行的欄位分隔符,預設分隔符為" "。可通過正則表達式指定分隔符,其實可以認為總是以正則方式指定分隔符。

以下是幾個示例和需要註意的空格分隔符:

  1. -F " ":預設的,會壓縮所有前導空白,包括製表符和空格。
  2. -F " :":當空格後跟一個冒號時作為分隔符。會壓縮前導空格,但不會匹配製表符,更不會壓縮製表符。
  3. -F "[ ]':只表示一個空格,不壓縮任何空白。
  4. -F "|":指定豎線作為分隔符。
  5. -F ",[ \t]*|[ \t]+":逗號後跟0或多個空白,或者只有1或多個空白時作為分隔符。

也就是說,當空格寫在最前面且不被中括弧包圍限制的時候,總會忽略前導空格,但不一定能匹配製表符。

使用內置變數"RS"可以控制輸入行的行分隔符,預設為"\n",只有遇到行分隔符時才作為"一行"記錄被讀取。

將其讀作行分隔符不標準,應該讀為"記錄分隔符"。例如設置以製表符作為記錄分隔符。

RS="\t"

記錄分隔符變數"RS"只識別第一個字元,若設置為"\t\t",則第二個"\t"被忽略。但是控制輸出記錄分隔符的內置變數OFS則可識別多字元。

可通過設置FS="\n";RS=""使得awk能處理多行記錄。但此時,原本的每行數據整體變成一個欄位。

4.BGEIN和END

BEGIN和END是一個特殊的PATTERN,BEGIN引導的程式是在awk讀取第一個文件第一行前要執行的awk程式,END引導的程式是在awk處理完最後一個文件最後一行後要執行的awk程式。通常BEGIN用於輸出一個標題,或者初始化一些格式、變數等,END則用於最後的總結性輸出。

所以awk稍微完整一點的格式為:

BGEIN{ACTIONS}PATTERN{ACTIONS}END{ACTIONS}

刨去BEGIN和END引導的兩個程式,中間處理輸入文件的程式PATTER{ACTIONS}稱為"主輸入迴圈(main input loop)"。在進入主輸入迴圈之前,可以不用提供輸入流,但進入主輸入迴圈後,必須提供輸入流。

例如,在開始處理文件前,設置輸出報表的頭部,在最後輸出總共輸出了多少行。其中print ""表示輸出一個空行。

BEGIN{print "ID NAME GENDER GENDER";print ""}{print $0}END{print "total num: " NR}

5.數組

awk的數組和shell的數組類似,都支持數值index的普通數組和字元串index的關聯數組,其實數值index仍然會轉換成字元串格式的index,所以awk的數組類型都是關聯數組。

數組格式:array_name[index]
數值賦值:array_name[1]=value1
引用數組:array_name[1]

需要註意的是,關聯數組的index必須使用雙引號包圍,例如array_name["ma"],如果寫成array_name[ma],則表示使用變數"ma"的值作為index。若"ma"變數未定義,則這會定義一個新的數組array_name[""]

使用index in array_name的方式可以判斷數組array_name中是否有index下標對應的數組元素。如果有,它會返回1,否則返回0。所以判斷語句可以如下:

if ( "ma" in array_name )

其實,判斷某個數組變數的值是否為空也可判斷該數組元素是否存在,如下。但這有副作用,當該元素不存在時,會創建它。

if ( array_name["ma"] != "" )

for迴圈的一種變體:

for (i in array_name){
    do something about array_name[i]
}

可以用於變數數組,其中變數"i"是變數數組時的index,array_name是數組名。這是以遍歷index的方式遍曆數組。由於index的順序隨機,所以遍歷時順序也是隨機的。當然,遍曆數組的方式有多種,以上只是for迴圈遍歷的一種方式。

使用delete語句可以刪除數組中的元素或者刪除整個數組。如下:

delete array_name["ma"]  # 刪除array_name中下標為ma的元素
delete array_name        # 刪除數組array_name

6.流程式控制制語句

在ACTION中,可以使用流程式控制制語句。包括但不限於:

if (expression) statements
if (expression) statements else statements
while (expression) statements
for (expression; expression; expression) statements
for (expression in array) statements
do statements while (expression)

還有幾個能影響迴圈的動作:

break:退出迴圈。
continue:退出當前迴圈,進入下一個迴圈
next:讀入下一行,並awk程式的頂端從頭開始。這個awk程式是PATTERN{action}這部分,不包括BEGIN{action}exit code:直接進入END,若本就在END中,則直接退出awk。如果END中的exit沒有定義code,則採用前一個exit的code。

6.1 條件判斷語句

if格式:

PATTERN {
  if (test_cmd){
      cmd1
      cmd2
      ...
  }
}

if-else格式為:

PATTERN {
   if (test_cmd){
      cmd1
      cmd2
      ......
      }
   else
      cmd3
}

當if或else結構中的命令只有一個,則其內可省大括弧,如果超過一個,則需要使用大括弧。

若採用一行書寫格式,則如下:

PATTERN {if (test_cmd){cmd1;cmd2;...}else {cmd3;cmd4...}}

還有if-else if-else格式。

PATTERN {
    if (test_cmd){cmd_list1}
    else if {cmd_list2}
    else if {cmd_list3}
    else {cmd_list}
}

還支持多目操作符。

expression ? action1 : action2

其中"?"和":"還可以繼續嵌套。

6.2 while迴圈

結構:

PATTERN {
  cmd1
  while (test_cmd)
      cmd
}

當cmd有多個時,使用大括弧包圍。

PATTERN {
    cmd1
    while (test_cmd){
        cmd2
        cmd3
        ....
    }
}

一行書寫格式:

PATTERN{cmd1;while (test_cmd){cmd1;cmd2}}

6.3 do迴圈

和while迴圈類似,地位和shell中的until迴圈一樣。都是至少執行一次命令列表。

結構:

PATTERN {
    do{
        cmd1
        cmd2
    } while (test_cmd)
}

6.4 for迴圈

結構大致如下:

PATTERN {
    for (i=1;i<=10;++i){
    cmd1
    cmd2
    }
}

for後括弧中包括:變數初始值,條件判斷和計數器增長表達式。

7.更完整的awk程式格式和表達式

更完整的awk程式的語法格式有以下幾種:

BEGIN{actions}
END{actions}
expr{actions}
/regexp/{actions}:可被regexp匹配的行才執行actions
expr1,expr2{actions}:表示範圍,從滿足expr1的行開始,到滿足expr2的行結束

其中:

  • expr是表達式。
    • 比較操作符有:< <= == != >= > ~ !~
    • 算術操作符有:+ - * / % ^(取冪) **(取冪)。其中**非POSIX標準,不可移植。
    • 賦值操作符有:++ -- += -= *= /= %= ^= **=。awk支持複合賦值,例如FS = OFS = "\t"表示欄位分隔符和輸出欄位分隔符都被賦值為製表符。
  • /regexp/為正則匹配模式,表示該行能被regexp匹配則為真。還有以下兩種匹配表達式,分別表示給定的字元串能(不能)匹配就為真。
    • string ~ /regexp/
    • string !~ /regexp/
  • 還有符合模式的表達式。使用邏輯操作符"&&"、"||"和"!"連接。如$4 == "Asia" && $3 > 500! (NR > 1 && NF > 3)

awk中字元串和數值數據類型是自動轉換的。如果想要得到一個字元串值,可以value ""進行轉換,同理,如果想要得到一個數值,可以value + 0

另外,正則表達式可以不用包圍在兩個斜杠中。可以將正則表達式賦值給一個變數,然後使用該變數取匹配數據。例如:

reg="^[0-9]+$"
$2 ~ reg

甚至直接使用雙引號替換斜杠也允許。但不建議使用,因為一個元字元可能需要多個反斜杠來保護,使得看上去極其晦澀。

8.awk中的變數

普通變數:給變數賦值時,如果要賦值字元串,則該字元串應該使用雙引號包圍,特別是包含特殊字元時。賦值數值時無所謂。 欄位變數:$1,$2,$3,...,$NF,還有"$0"表示整行內容。另外,可以直接賦值一個新欄位或修改欄位值。但這都會影響"$0"。同理,修改"$0"也會影響各欄位值。
內置變數:其實可以分為兩類,一類是awk內部自動修改的變數,如行數變數NR,一類是內部不會改動的系統變數,如輸入欄位分隔符變數FS,完全需要手動修改,這類一般都有預設值。

  • ARGV:命令行參數數組。從0開始計數知道ARGC-1。
  • ARGC:ARGV數組元素的個數。
  • FILENAME:當前處理的文件名。
  • FNR:當前處理文件的記錄號。(file record num)
  • NR:已處理的總記錄數。多個文件時不重置。(record num)
  • NF:當前記錄的欄位總數。(field num)
  • FS:輸入的欄位分隔符。預設為空白。(file separate)
  • OFS:輸出的欄位分隔符。預設為空白。(output record separate)
  • RS:輸入流的記錄分隔符。預設為"\n"。該變數只取值第一個字元。(record separate)
  • ORS:輸出流的記錄分隔符。預設為"\n"。該變數只取值的第一個字元。(output record separate)
  • OFMT:printf輸出數值轉換成字元串輸出時的格式。預設為"%.6g"。
  • CONVFMT:printf輸出數值轉換成字元串輸出時的格式。會被OFMT覆蓋。預設為"%.6g"。
  • RLENGTH:被match函數匹配的字元串的長度。
  • RSTART:被match函數匹配的字元串的開始位置。
  • SUBSEP:下標分隔符。預設為"\034",ASCII中034代表的是雙引號'"'。

註意,像NR、FNR、RS等的對象是記錄(record),而非行。只有當RS="\n"時,讀取了一行才表示讀取了一條記錄。

9.awk中的內置函數

awk有兩類內置函數:算術函數和字元串函數。還支持自定義函數。

算術函數:

  • cos(x):取x的餘弦。
  • sin(x):取x的正弦。
  • sqrt(x):取x的平方根。
  • rand():返回一個隨機數r,其中0<=r<1
  • srand(x):設置rand()的種子值為x。種子值相同時,rand()的結果相同。可print srand()輸出當前種子值。
  • int(x):取x的整數部分。

因此,要生成一個範圍[1,n]的隨機數,使用int(n*rand() + 1),要四捨五入一個數值,使用int(x + 0.5)

隨機數的種子值相同時,rand的結果總是相同。如下兩次運行結果,兩次結果中,前兩個rand()值相同,後兩個rand()值不同,因為中間使用了srand()重設種子值。

awk 'BEGIN{print rand();print rand();srand();print rand();print rand();print srand()}'
  0.237788
  0.291066
  0.109925
  0.983692
  1504560578
awk 'BEGIN{print rand();print rand();srand();print rand();print rand();print srand()}'
  0.237788
  0.291066
  0.96322
  0.670495
  1504560604

字元串函數:建議下麵的所有regexp都使用"//"包圍。

  • index(str1,str2):返回子串str2在字元串str1中第一次出現的位置。如果沒有指定str1,則返回0。
  • length(str1):返回字元串str1的長度。如果未給定str1,則表示計算"$0"的長度。
  • substr(str1,p):返回str1中從p位置開始的尾碼字元串。
  • substr(str1,p,n):返回str1中從p位置開始,長度為n的子串。
  • match(str1,regexp):如果regexp能匹配str1,則返回匹配起始位置。否則返回0。它會設置內置變數RSTART和RLENGTH的值。
  • split(str1,array,sep):使用欄位分隔符sep將str1分割到數組array中,並返回數組的元素個數。如果未指定sep則採用FS的值。因此該函數用於切分欄位到數組中,下標從1開始。
  • sprintf(fmt,expr):根據printf的格式fmt,返回格式化後的expr。
  • sub(regexp,rep,str2):將str2中第一個被regexp匹配的字元串替換成rep,替換成功則返回1(表示替換了1次),否則返回0。註意是貪婪匹配。
  • sub(regexp,rep):將"$0"中第一個被regexp匹配的字元串替換成rep,替換成功則返回1,否則返回0。註意是貪婪匹配。
  • gsub(regexp,rep,str2):將str2中所有被regexp匹配的內容替換成rep,並返回替換的次數。
  • gsub(regexp,rep):將"$0"中所有被regexp匹配的內容替換成rep,並返回替換的次數。
  • toupper(str):將str轉換成大寫字母,並返回新串。
  • tolower(str):將str轉換成小寫字母,並返回新串。

關於替換函數sub和gsub,可以在替換字元串rep中使用"&"符號表示反向引用,引用的是整個被匹配的部分。

awk 'BEGIN{
    print index("banana","na")
    print length("banana")
    print match("banana","na.*")
    print toupper("banana")
    print substr("banana",3)}' 
3
6
3
BANANA
nana
awk 'BEGIN{str1="x&x";str2="banana"
        print sub(/a.*n/,str1,str2)
        print str2}' 
1
bxananxa
awk 'BEGIN{
    print match("banana",/a.*n/)
    print RSTART,RLENGTH}'
2
2 4
awk 'BEGIN{print sprintf("hello %i world %5s","123","abc")}'
hello 123 world   abc
awk 'BEGIN{
    name="Ma long shuai"
    split(name,myname)
    for (i in myname){
        print myname[i]}
    }'
Ma
long
shuai

縱觀上述字元串函數,沒有一個函數可以將匹配成功的字元串輸出出來。但藉助match()和RSTART、RLENGTH可以實現。

例如,取出"Ma:long:shuai"中的"long"並輸出。

awk 'BEGIN{
    name="Ma:long:shuai"
    if (match(name,/:[^:]*:/)){
        print substr(name,RSTART+1,RLENGTH-2)}}'
long

10.自定義函數

function name(parameter-list) {
    statements
}

函數中的變數不影響函數外的變數,但可以使用外部變數。參數列表使用逗號分隔,這些參數只在函數內部生效。

可以在awk的引號內任意位置處定義函數(即使是BEGIN之前或END之後),且函數的調用位置可以在函數的定義位置之前。但註意,函數必須不能定義在BEGIN或主輸入迴圈或END內部,否則自定義函數的大括弧會和包圍action的大括弧衝突而報錯。即如下(1)-(4)處位置可定義定義函數,在任意位置處調用函數。

awk '(1)BEGIN{ACTIONS}(2)PATTERN{ACTIONS}(3)END{ACTIONS}(4)'

在函數的statements中,可以使用return expression語句,表示函數的返回值。

例如,創建一個"向字元串指定位置處插入一個字元"的函數。

awk 'function insert(STRING, POS, INS) {
    before_tmp = substr(STRING, 1, POS)
    after_tmp = substr(STRING, POS + 1)
    return before_tmp INS after_tmp
}
BEGIN{print insert("banana",3,"x")}'

11.getline函數

getline函數用於從文件、標準輸入或管道中讀取數據,並按情況設置變數的值。getline可以自動不斷的載入下一行。如果能讀取記錄,則getline的返回值為1,遇到輸入流的尾部時,返回值為0,不能讀取記錄(如文件沒有讀取許可權、文件不存在)時,返回值為“-1"。

其中:

  • getline:會從主輸入文件中讀取記錄。會同時設置$0,NF,NR,FNR。
  • getline var:會從主輸入文件中讀取記錄,並將讀取的記錄賦值給變數var。會同時設置var,NR,FNR。
  • getline <file:從外部文件file中讀取記錄。同時會設置$0,NF。
  • getline var <file:從外部文件file中讀取記錄,並將讀取的記錄賦值給變數var。會同時設置var。
  • cmd | getline:從管道中讀取記錄。會同時設置$0,NF。
  • cmd | getline var:從管道中讀取記錄,並將讀取的記錄賦值給變數var。會同時設置var。

也就是說:

  1. 當getline從非主輸入文件讀取記錄時,不會設置NR和FNR;
  2. 當getline後沒有給定變數var時,會將讀取的記錄賦值給$0,於是會同時設置NF並切分成欄位;否則將讀取的記錄賦值給變數var,不會設置NF切分欄位。

仍然註意,從外部文件file中讀取記錄時,需要使用雙引號包圍文件名,否則被當成awk中的變數。

例如,執行Linux下的who命令並傳遞給getline讀取,每讀取一行記錄,變數n自增1。

while ("who" | getline)
n++

將Linux命令date的結果保存到awk的變數date中。

"date" | getline date

當寫成迴圈時,如:

while (getline <"file"){
    cmd...
}

這是不安全的,因為當無法讀取file時,返回值為"-1",而while迴圈的判斷條件是0和非0,所以"-1"也會進入死迴圈。所以,安全的寫法為:

while (getline <"file" >0){
    cmd...
}

12.向awk傳遞變數

awk很重要且必備的能力是接受外界的變數,例如shell中的變數,shell中命令執行的結果,或者是在開始執行awk前應該初始化的變數。

例如,在shell中定義一個變數name,傳遞給awk使用。

awk -v awk_name="$name" 'BEGIN{print awk_name}' 
Ma longshuai

有三種方式可以向awk傳遞變數:

1.將待傳遞變數當作文件名被awk解析。awk識別後發現是賦值語句,就認為其是變數傳遞。變數賦值語句必須定義awk program之後。此法定義的變數不可在BEGIN中使用,因為它是被當成文件解析的,只有在需要讀取主輸入文件的時候才會被解析。

awk 'BEGIN{}PATTERN{print var1,var2,var3}' var1=value1 var2=value2 file1 var3=value3 var1=value4 file2

在上面的語句中,當awk執行完BEGIN程式後,準備讀取主輸入,於是開始解析program後的輸入文件。解析時發現,var1和var2都是賦值語句,於是當成變數處理,當讀取到file1時,發現只有一個參數,則當作輸入文件,於是開始處理該文件。在處理file1時,var1和var2都是有效的,但var3還未賦值,因此var3無效。當處理完file1後,繼續解析下一個主輸入文件,此時var3被賦值,並開始處理file2。在處理file2時,var1、var2和var3都是有效的,但var1被新值覆蓋。

此外,還可以將shell命令的結果賦值給這些預定義變數。如下展示了幾種變數定義的方式:

name="Ma longshuai"
awk 'program' OFS=":" var1="$name" var2="`echo Ma longshuai2`" var3="Ma longshuai3" var4=Malongshuai4 filename

不僅可以定義普通變數,還可以定義內置變數(如上OFS)。註意加引號的方式:為了安全,應該對所有賦值語句的value部分加上雙引號,除非所賦的值不包含特殊字元。所以,如果上面的var1賦值語句寫成var1=$name,將被awk解析成var1=Ma longshuai,於是var1的值為Ma,主輸入文件為longshuai。

 

2.使用"-v"選項傳遞。變數賦值語句必須定義在awk program之前。這種方法定義的變數可以在BEGIN程式中使用。

除了定義在program之前,定義方式同上。每定義一個變數,都需要使用一個"-v"選項。如:

name="Ma longshuai"
awk -v OFS=":" -v var1="$name" -v var2="`echo Ma longshuai2`" -v var3="Ma longshuai3" 'program' filename

 

3.通過參數數組ARGV的方式。

ARGV是內置的數組變數。awk內部會將命令行切分,並按規則將各參數存放到ARGV數組中,數組下標從0開始,這是awk中唯一下標從0開始的數組。在存放到ARGV時,所有的選項和program會被忽略。

每存儲一個數組變數,特殊變數ARGC的值增加1。因此ARGC的值代表的是參數的個數。所以,數組變數從ARGV[0]到ARGV[ARGC-1]。

可使用類似下麵的迴圈來遍歷ARGV數組。

awk -F "\t" -v var1="value1" 'BEGIN{
        for(i=0;i<ARGC;++i){
            print "ARGV[" i "]: " ARGV[i]
        }
        print "ARGC: " ARGC
    }' "a" "b" "v=1" file 
  ARGV[0]: awk
  ARGV[1]: a
  ARGV[2]: b
  ARGV[3]: v=1
  ARGV[4]: file
  ARGC: 5

註意,ARGV[0]存儲的是awk命令,"-F"和"-v"選項都沒有存儲到ARGV中。

ARGC和ARGV數組變數的值都可以手動修改。命令行分割存儲完成之後,開始處理BEGIN,再處理主迴圈輸入。因此,在BEGIN中修改ARGV中輸入文件對應的值,可以改變awk所讀取的輸入文件,若將其設置為空,則該數組變數直接被跳過,也就不再讀取該輸入文件。

需要註意的是,當增加ARGV元素時,必須同時遞增ARGC的值,因為awk是根據AGRC來讀取ARGV的。同理,只增加ARGC的值,將導致新建ARGV數組元素,且這些新元素的值為空。也因此,如果減小ARGC的值,將導致無法訪問超出ARGC-1邊界的ARGV元素。

 

回到系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7509812.html

註:若您覺得這篇文章還不錯請點擊下右下角的推薦,有了您的支持才能激發作者更大的寫作熱情,非常感謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、什麼是資料庫? 資料庫(Database)是按照數據結構來組織、存儲和管理數據的建立在電腦存儲設備上的倉庫。 簡單來說是本身可視為電子化的文件櫃——存儲電子文件的處所,用戶可以對文件中的數據進行新增、截取、更新、刪除等操作。 1、文件夾可視為資料庫; 2、excel可視為數據表; 3、一條記錄 ...
  • 1.hadoop2.x 概述 hadoop2中NameNode可以有多個(目前只支持2個)。每一個都有相同的職能。一個是active狀態的,一個是standby狀態的。當集群運行時,只有active狀態的NameNode是正常工作的,standby狀態的NameNode是處於待命狀態的,時刻同步ac ...
  • 1.usb 可以使用此命令讀取u盤裡的內容,此命令加上相關參數可以有以下功能: 1.1usb start 在使用u盤之前必須啟動此命令以初始化好fat文件系統環境,筆者的輸出如下: jello # usb start(Re)start USB...USB: Starting the controll ...
  • 原文發表於cu:2016-06-23 參考文檔: saltstack的安裝與簡單配置,應用。 一.環境 Server:CentOS Linux release 7.2.1511 (Core) Salt-master:172.18.12.201 Salt-minion:172.18.12.204 二. ...
  • 配置文件 在主節點初始化複製集配置 在主節點上添加從節點 修改節點的優先順序,設置為0則不會被選為主 ...
  • 要求:linux 卸載 mongo2.6 版本:linux系統:Ubuntu 16.04 mongo: mongo 2.6.12 1、 查看安裝的mongo版本和服務 # dpkg –l | grep mongo 可以看到,目前有三個和mongodb有關,mongodb,mongodb-client ...
  • 第1章 Linux命令基礎 1.1 習慣 操作前備份,操作後檢查 1.2 簡單目錄結構 一切從根開始,與windows不同 1.3 規則 [root@oldboyedu-40 ~]# [用戶名@主機名 你在哪]# [root@oldboyedu-40 ~]# [用戶名@主機名 你在哪]# 1.4 重 ...
  • 從本地複製到遠程 從遠程複製到本地 說明 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...