SHELL的命令之a(chǎn)wk

      網(wǎng)友投稿 1153 2025-03-31

      awk命令功能是將一行分為數(shù)個(gè)“字段列”來(lái)處理,對(duì)表格化的文本處理能力超強(qiáng)。其語(yǔ)法及常用參數(shù)格式:

      awk [-參數(shù) 變量] 'BEGIN{初始化} 條件類(lèi)型1{動(dòng)作1} 條件類(lèi)型2{動(dòng)作2}。。。。END{后處理}'

      其中參數(shù)有:

      -F re:允許awk更改其字段分隔符

      -v var=$v 把v值賦值給var,如果有多個(gè)變量要賦值,那么就寫(xiě)多個(gè)-v,每個(gè)變量賦值對(duì)應(yīng)一個(gè)-v

      e.g. 要打印文件a的第num行到num+num1行之間的行,

      awk -v num=$num -v num1=$num1 'NR==num,NR==num+num1{print}' a

      -f progfile:允許awk調(diào)用并執(zhí)行progfile程序文件,當(dāng)然progfile必須是一個(gè)符合awk語(yǔ)法的程序文件。

      其中變量有:

      (1)awk內(nèi)置變量:

      ARGC? ? ? ? ?命令行參數(shù)的個(gè)數(shù)

      ARGV?? ? ? ? 命令行參數(shù)數(shù)組

      ARGIND ????當(dāng)前被處理文件的ARGV標(biāo)志符

      e.g 有兩個(gè)文件a 和b,文件處理的順序是先掃描完a文件,再掃描b文件:

      awk '{if(ARGIND==1){print "處理a文件"} if(ARGIND==2){print "處理b文件"}}' a b

      NR  ? ? 已經(jīng)讀出的記錄數(shù)

      FNR??  當(dāng)前文件的記錄數(shù)

      e.g 有兩個(gè)文件a 和b,文件處理的順序是先掃描完a文件,再掃描b文件:

      awk 'NR==FNR{print "處理文件a"} NR > FNR{print "處理文件b"}' a b

      說(shuō)明:輸入文件a和b,由于先掃描a,所以?huà)呙鑑的時(shí)候必然有NR==FNR,然后掃描b的時(shí)候,F(xiàn)NR從1開(kāi)始計(jì)數(shù),而NR則接著a的行數(shù)繼續(xù)計(jì)數(shù),所以NR > FNR

      e.g 要顯示文件的第10行至第15行

      awk 'NR==10,NR==15{print}' a

      SHELL的命令之a(chǎn)wk

      FS   ?輸入字段分隔符(缺省為:space:),相當(dāng)于-F選項(xiàng)

      awk -F ':' '{print}' a??? 和?? awk 'BEGIN{FS=":"}{print}' a 是一樣的

      OFS???? 輸出字段分隔符(缺省為:space:)

      awk -F ':' 'BEGIN{OFS=";"}{print $1,$2,$3}' b

      如果cat b為

      1:2:3

      4:5:6

      那么把OFS設(shè)置成";"后就會(huì)輸出

      1;2;3

      4;5;6

      (說(shuō)明:awk把分割后的第1、2、3個(gè)字段用$1,$2,$3...表示,$0表示整個(gè)記錄(一般就是一整行))

      NF???? 當(dāng)前記錄中的字段個(gè)數(shù)

      awk -F ':' '{print NF}' b的輸出為

      3

      3

      表明b的每一行用分隔符":"分割后都3個(gè)字段

      可以用NF來(lái)控制輸出符合要求的字段數(shù)的行,這樣可以處理掉一些異常的行

      awk -F ':' '{if (NF == 3)print}' b

      RS???? 輸入記錄分隔符,缺省為"\n"

      缺省情況下,awk把一行看作一個(gè)記錄;如果設(shè)置了RS,那么awk按照RS來(lái)分割記錄

      例如,如果文件c為

      hello world; I want to go swimming tomorrow;hiahia

      運(yùn)行 awk 'BEGIN{ RS = ";" } {print}' c 的結(jié)果為

      hello world

      I want to go swimming tomorrow

      hiahia

      合理的使用RS和FS可以使得awk處理更多模式的文檔,例如可以一次處理多行,例如文檔d為

      1 2

      3 4 5

      6 7

      8 9 10

      11 12

      hello

      每個(gè)記錄使用空行分割,每個(gè)字段使用換行符分割,這樣的awk也很好寫(xiě)

      awk 'BEGIN{ FS = "\n"; RS = ""} {print NF}' d 輸出

      2

      3

      1

      ORS:輸出記錄分隔符,缺省為換行符,控制每個(gè)print語(yǔ)句后的輸出符號(hào)

      awk 'BEGIN{ FS = "\n"; RS = ""; ORS = ";"} {print NF}' d 輸出

      2;3;1

      (2)awk讀取shell中的變量

      可以使用-v選項(xiàng)實(shí)現(xiàn)功能

      $b=1

      $cat f

      apple

      $awk -v var=$b '{print var, $var}' f

      1 apple

      shell調(diào)用awk實(shí)際上是fork一個(gè)子進(jìn)程出來(lái),而子進(jìn)程是無(wú)法向父進(jìn)程傳遞變量的,除非用重定向(包括管道)

      a=$(awk '{print $b, '$b'}' f)

      $echo $a

      apple 1

      其中,BEGIN和END中的語(yǔ)句分別在開(kāi)始讀取文件(in_file)之前和讀取完文件之后發(fā)揮作用,可以理解為初始化和掃尾。

      awk中使用重定向

      awk的輸出重定向類(lèi)似于shell的重定向。重定向的目標(biāo)文件名必須用雙引號(hào)引用起來(lái)。

      $awk '$4 >=70 {print $1,$2 >"destfile" }' filename

      $awk '$4 >=70 {print $1,$2 >>"destfile" }' filename

      awk中使用管道

      awk中的管道概念和shell的管道類(lèi)似,都是使用"|"符號(hào)。如果在awk程序中打開(kāi)了管道,必須先關(guān)閉該管道才能打開(kāi)另一個(gè)管道。也就是說(shuō)一次只能打開(kāi)一個(gè)管道。shell命令必須被雙引號(hào)引用起來(lái)?!叭绻蛩阍俅卧赼wk程序中使用某個(gè)文件或管道進(jìn)行讀寫(xiě),則可能要先關(guān)閉程序,因?yàn)槠渲械墓艿罆?huì)保持打開(kāi)狀態(tài)直至腳本運(yùn)行結(jié)束。注意,管道一旦被打開(kāi),就會(huì)保持打開(kāi)狀態(tài)直至awk退出。因此END塊中的語(yǔ)句也會(huì)收到管道的影響。(可以在END的第一行關(guān)閉管道)”

      awk中使用管道有兩種語(yǔ)法,分別是:

      awk output | shell input

      shell output | awk input

      對(duì)于awk output | shell input來(lái)說(shuō),shell接收awk的輸出,并進(jìn)行處理。需要注意的是,awk的output是先緩存在pipe中,等輸出完畢后再調(diào)用shell命令 處理,shell命令只處理一次,而且處理的時(shí)機(jī)是“awk程序結(jié)束時(shí),或者管道關(guān)閉時(shí)(需要顯式的關(guān)閉管道)”

      $awk '/west/{count++} {printf "%s %s\t\t%-15s\n", $3,$4,$1 | "sort +1"} END{close "sort +1"; printf "The number of sales pers in the western"; printf "region is " count "." }' datafile (解釋?zhuān)?west/{count++}表示與“wes”t進(jìn)行匹配,若匹配,則count自增)

      printf函數(shù)用于將輸出格式化并發(fā)送給管道。所有輸出集齊后,被一同發(fā)送給sort命令。必須用與打開(kāi)時(shí)完全相同的命令來(lái)關(guān)閉管道(sort +1),否則END塊中的語(yǔ)句將與前面的輸出一起被排序。此處的sort命令只執(zhí)行一次。

      在shell output | awk input中awk的input只能是getline函數(shù)。shell執(zhí)行的結(jié)果緩存于pipe中,再傳送給awk處理,如果有多行數(shù)據(jù),awk的getline命令可能調(diào)用多次。

      $awk 'BEGIN{ while(("ls" | getline d) > 0) print d}' f

      輸出滿(mǎn)足某一條件的所有行的值

      cat outest.txt | awk '$3<0.001 {print $1, $2 >>"test1.txt"}' >test2.txt

      $n????????$1 the first parameter,$2 the second...

      $#????????The?number?of?command-line?parameters.

      $0????????The?name?of?current?program.

      $?????????Last?command?or?function's?return?value.

      $$????????The?program's?PID.

      $!????????Last?program's?PID.

      $@????????Save?all?the?parameters.

      實(shí)例1:文件a,統(tǒng)計(jì)文件a的第一列中是浮點(diǎn)數(shù)的行的浮點(diǎn)數(shù)的平均值。

      $cat a

      1.021 33

      1#.ll ? 44

      2.53 6

      ss ? ?7

      awk 'BEGIN{total = 0;len = 0} {if($1~/^[0-9]+\.[0-9]*/){total += $1; len++}} END{print total/len}' a

      說(shuō)明:$1~/^[0-9]+\.[0-9]*/表示$1與“/ /”里面的正則表達(dá)式進(jìn)行匹配,若匹配,則total加上$1,且len自增,即數(shù)目加1.“^[0-9]+\.[0-9]*”是個(gè)正則表達(dá)式,“^[0-9]”表示以數(shù)字開(kāi)頭,“\.”是轉(zhuǎn)義的意思,表示“.”為小數(shù)點(diǎn)的意思。“[0-9]*”表示0個(gè)或多個(gè)數(shù)字。

      實(shí)例2:將d文件性別合并到c文件

      $ cat c

      zhangsan 100

      lisi 200

      wangwu 300

      $ cat d

      zhangsan man

      lisi woman

      方法1:$ awk ?'FNR==NR{a[FNR]=$0;next}{if($1 in a) print a[FNR],$2}' c d

      實(shí)例3:找不同記錄(同上,取反)

      $ awk 'FNR==NR{a[$0];next}!($0 in a)' a b

      $ awk 'FNR==NR{a[$0]=1;next}!a[$0]' a b

      $ awk 'ARGIND==1{a[$0]=1}ARGIND==2&&a[$0]!=1' a b

      $ awk 'FILENAME=="a"{a[$0]=1}FILENAME=="b"&&a[$0]!=1' a b

      7

      8

      方法2:$ sort a b |uniq -d

      方法3:$ grep -vf a b

      實(shí)例4:合并兩個(gè)文件

      1)將d文件性別合并到c文件

      方法1:$ awk ?'FNR==NR{a[$1]=$0;next}{print a[$1],$2}' c d

      zhangsan 100 ?man

      lisi 200 woman

      wangwu 300 man

      方法2:$ awk ?'FNR==NR{a[FNR]=$0}NR>FNR{print a[FNR],$2}' c d

      說(shuō)明:NR==FNR匹配第一個(gè)文件,NR>FNR匹配第二個(gè)文件,將$1為數(shù)組下標(biāo)

      方法3:$ awk 'ARGIND==1{a[FNR]=$0}ARGIND==2{print a[FNR],$2}' c d

      2)將a.txt文件中服務(wù)名稱(chēng)合并到一個(gè)IP中

      $ cat a.txt

      192.168.2.100 : httpd

      192.168.2.100 : tomcat

      192.168.2.101 : httpd

      192.168.2.101 : postfix

      192.168.2.102 : mysqld

      192.168.2.102 : httpd

      $ awk -F: -vOFS=":" '{a[$1]=a[$1] $2}END{for(i in a)print i,a[i]}' a.txt

      $ awk -F: -vOFS=":" '{a[$1]=$2 a[$1]}END{for(i in a)print i,a[i]}' a.txt

      192.168.2.100 : httpd ?tomcat

      192.168.2.101 : httpd ?postfix

      192.168.2.102 : mysqld ?httpd

      說(shuō)明:a[$1]=$2 第一列為下標(biāo),第二個(gè)列是元素,后面跟的a[$1]是通過(guò)第一列取a數(shù)組元素(服務(wù)名),結(jié)果是$1=$2 $2,并作為a數(shù)組元素。

      3)將第一行附加給下面每行開(kāi)頭

      $ cat a.txt

      xiaoli

      a 100

      b 110

      c 120

      $ awk 'NF==1{a=$0;next}{print a,$0}' a.txt

      $ awk 'NF==1{a=$0}NF!=1{print a,$0}' a.txt

      xiaoli ?a 100

      xiaoli ?b 110

      xiaoli ?c 120

      實(shí)例5:倒敘列打印文本

      $ cat a.txt

      xiaoli ? a 100

      xiaoli ? b 110

      xiaoli ? c 120

      $ awk '{for(i=NF;i>=1;i--){printf "%s ",$i}print s}' a.txt

      100 a xiaoli

      110 b xiaoli

      120 c xiaoli

      $ awk '{for(i=NF;i>=1;i--)if(i==1)printf $i"\n";else printf $i" "}' a.txt

      說(shuō)明:利用NF降序輸出,把最后一個(gè)域作為第一個(gè)輸出,然后自減,print s或print ""打印一個(gè)換行符

      實(shí)例6:從第二列打印到最后

      方法1:$ awk '{for(i=2;i<=nf;i++)if(i==nf)printf $i"\n";else printf $i" "}' a.txt< p>

      方法2:$ awk '{$1=""}{print $0}' a.txt

      a 100

      b 110

      c 120

      實(shí)例7:將c文件中第一列放到到d文件中的第三列

      $ cat c

      a

      b

      c

      $ cat d

      1 one

      2 two

      3 three

      方法1:$ awk 'FNR==NR{a[NR]=$0;next}{$3=a[FNR]}1' c d

      說(shuō)明:以NR編號(hào)為下標(biāo),元素是每行,當(dāng)處理d文件時(shí)第三列等于獲取a數(shù)據(jù)FNR(重新計(jì)數(shù)1-3)編號(hào)作為下標(biāo)。

      方法2:$ awk '{getline f<"c";print $0,f}' d< p>

      1 one a

      2 two b

      3 three c

      1)替換第二列

      $ awk '{getline f<"c";gsub($2,f,$2)}1' d< p>

      1 a

      2 b

      3 c

      2)替換第二列的two

      $ awk '{getline f<"c";gsub("two",f,$2)}1' d< p>

      1 one

      2 b

      3 three

      實(shí)例8:數(shù)字求和

      方法1:$ seq 1 100 |awk '{sum+=$0}END{print sum}'

      方法2:$ awk 'BEGIN{sum=0;i=1;while(i<=100){sum+=i;i++}print sum}'< p>

      方法3:$ awk 'BEGIN{for(i=1;i<=100;i++)sum+=i}end{print sum}' dev null< p>

      方法4:$ seq -s + 1 100 |bc

      實(shí)例9:每隔三行添加一個(gè)換行符或內(nèi)容

      方法1:$ awk '$0;NR%3==0{printf "\n"}' a

      方法2:$ awk '{print NR%3?$0:$0"\n"}' a

      方法3:$ sed '4~3s/^/\n/' a

      實(shí)例10:字符串拆分

      方法1:

      $ echo "hello" |awk -F '' '{for(i=1;i<=nf;i++)print $i}'< p>

      $ echo "hello" |awk -F '' '{i=1;while(i<=nf){print $i;i++}}'< p>

      h

      e

      l

      l

      o

      方法2:

      $ echo "hello" |awk '{split($0,a,"''");for(i in a)print a[i]}' ?#無(wú)序

      l

      o

      h

      e

      l

      實(shí)例11:統(tǒng)計(jì)字符串中每個(gè)字母出現(xiàn)的次數(shù)

      $ echo a,b.c.a,b.a |tr "[,. ]" "\n" |awk -F '' '{for(i=1;i<=nf;i++)a[$i]++}end{for(i in a)print i,a[i]|"sort -k2 -rn"}'< p>

      a 3

      b 2

      c 1

      實(shí)例12:第一列排序

      $ awk '{a[NR]=$1}END{s=asort(a,b);for(i=1;i<=s;i++){print i,b[i]}}' a.txt< p>

      說(shuō)明:以每行編號(hào)作為下標(biāo)值為$1,并將a數(shù)組值放到數(shù)組b,a下標(biāo)丟棄,并將asort默認(rèn)返回值(原a數(shù)組長(zhǎng)度)賦值給s,使用for循環(huán)小于s的行號(hào),從1開(kāi)始到數(shù)組長(zhǎng)度打印排序好的數(shù)組。

      實(shí)例13:刪除重復(fù)行,順序不變

      $ awk '!a[$0]++' file

      實(shí)例14:刪除指定行

      刪除第一行:

      $ awk 'NR==1{next}{print $0}' file #$0可省略

      $ awk 'NR!=1{print}' file

      $ sed '1d' file

      $ sed -n '1!p' file

      實(shí)例15:在指定行前后加一行

      在第二行前一行加txt:

      $ awk 'NR==2{sub('/.*/',"txt\n&")}{print}' a.txt

      $ sed'2s/.*/txt\n&/' a.txt

      在第二行后一行加txt:

      $ awk 'NR==2{sub('/.*/',"&\ntxt")}{print}' a.txt

      $ sed'2s/.*/&\ntxt/' a.txt

      實(shí)例16:通過(guò)IP獲取網(wǎng)卡名

      $ ifconfig |awk -F'[: ]' '/^eth/{nic=$1}/192.168.18.15/{print nic}'

      實(shí)例17:浮點(diǎn)數(shù)運(yùn)算(數(shù)字46保留小數(shù)點(diǎn))

      $ awk 'BEGIN{print 46/100}'

      $ awk 'BEGIN{printf "%.2f\n",46/100}'

      $ echo 46|awk '{print $0/100}'

      $ echo 'scale=2;46/100' |bc|sed 's/^/0/'

      $ printf "%.2f\n" $(echo "scale=2;46/100" |bc)

      結(jié)果:0.46

      實(shí)例18:替換換行符為逗號(hào)

      $ cat a.txt

      1

      2

      3

      替換后:1,2,3

      方法1:

      $ awk '{s=(s?s","$0:$0)}END{print s}' a.txt

      說(shuō)明:三目運(yùn)算符(a?b:c),第一個(gè)s是變量,s?s","$0:$0,第一次處理1時(shí),s變量沒(méi)有賦值初值是0,0為假,結(jié)果打印1,第二次處理2時(shí),s值是1,為真,結(jié)果1,2。以此類(lèi)推,小括號(hào)可以不寫(xiě)。

      方法2:

      $ tr '\n' ',' < a.txt

      實(shí)例19.統(tǒng)計(jì)第一列的數(shù)據(jù)分布

      awk -F '\t' '{sum[$1]++}END{for(i in sum) print i "\t" sum[i]}' example.txt

      補(bǔ)充::

      可以將待篩選的用戶(hù)id存入一個(gè)文件userid.txt。一行一個(gè)id。過(guò)濾data.txt,找到userid.txt中的用戶(hù)id的數(shù)據(jù)來(lái)輸出。

      awk -F '\t' 'BEGIN{while(getline<"userid.txt") a[$1]=1;} {if(a[$2]==1) print $0;}' data.txt > new_data.txt

      BEGIN語(yǔ)法是在逐行解析之前執(zhí)行的一段代碼。這里它會(huì)加載userid.txt將用戶(hù)id存入關(guān)聯(lián)數(shù)組a中:key是用戶(hù)id,value是1。

      后面的代碼塊開(kāi)始逐行解析,用data.txt的第二列做key去關(guān)聯(lián)數(shù)組a中查找。如果查找到value為1,就輸出整行。

      Shell

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶(hù)投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶(hù)投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:wps除法公式怎么輸入
      下一篇:MRS管理面混合云場(chǎng)景自動(dòng)化升級(jí)
      相關(guān)文章
      亚洲国产成人久久三区| 无码欧精品亚洲日韩一区| 亚洲Aⅴ无码专区在线观看q| 国内成人精品亚洲日本语音| 亚洲日本天堂在线| 亚洲综合中文字幕无线码| 亚洲二区在线视频| 国产日本亚洲一区二区三区| 亚洲噜噜噜噜噜影院在线播放| 亚洲美女免费视频| 亚洲第一精品福利| 久久精品九九亚洲精品| 久久久久久亚洲Av无码精品专口 | 亚洲国产精品一区二区久久| 人人狠狠综合久久亚洲婷婷| 亚洲精品国偷自产在线| 亚洲精品美女久久777777| 人人狠狠综合久久亚洲88| 水蜜桃亚洲一二三四在线| 久久久青草青青亚洲国产免观| 久久精品国产亚洲网站| 久久精品亚洲综合| 夜夜亚洲天天久久| 91亚洲自偷在线观看国产馆| 亚洲人成网国产最新在线| 亚洲日韩国产AV无码无码精品| 亚洲精品无码久久久久秋霞| 亚洲av无码专区国产不乱码 | 亚洲AV女人18毛片水真多| 精品亚洲福利一区二区| 亚洲一级特黄大片无码毛片| 在线观看亚洲av每日更新| 亚洲AV无码成人专区片在线观看| 亚洲免费视频网站| 亚洲伊人久久大香线焦| 亚洲美国产亚洲AV| 亚洲国产精品成人久久蜜臀 | 亚洲精品国产精品乱码在线观看 | 国产精品亚洲精品日韩动图| 亚洲无码日韩精品第一页| 亚洲国产精品VA在线观看麻豆|