使用awk取某一行數據中的倒數第N列:$(NF-(n-1))
好比取/etc/passwd文件中的第2列、倒數第一、倒數第二、倒數第4列(以冒號爲分隔符)。($NF表示倒數第一列,$(NF-1)表示倒數第二列)node
[root@ipsan-node06 ~]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin [root@ipsan-node06 ~]# awk -F":" '{print $2,$(NF),$(NF-1),$(NF-3)}' /etc/passwd x /bin/bash /root 0 x /sbin/nologin /bin 1 x /sbin/nologin /sbin 2 x /sbin/nologin /var/adm 4 x /sbin/nologin /var/spool/lpd 7 x /bin/sync /sbin 0 x /sbin/shutdown /sbin 0 x /sbin/halt /sbin 0 x /sbin/nologin /var/spool/mail 12 x /sbin/nologin /root 0
linux實現將文本文件每一行中相同第一列對應的其餘列進行拼接linux
[root@jump-v4 ~]# sort b.txt|uniq 1 34 1 49 2 45 2 48 3 54 3 57 3 89 [root@jump-v4 ~]# sort b.txt|uniq|awk '{a[$1]=(a[$1]" "$2);} END{for(i in a) print i ":"a[i]}' 1: 34 49 2: 45 48 3: 54 57 89 命令解析: 1)首先sort test|uniq實現對test文件的去重,去掉了重複的 1 49,保留不一樣的行; 2)awk '{a[$1]=(a[$1]" "$2);} END{for(i in a) print i ":"a[i]}' 表示的含義是: 將每一行的第一列最爲數組a的key, 第二列做爲a的value,同時碰到相同的key,就把其值進行拼接,linux的shell的字符串拼接形式爲str = (str 「 」 $var), 最後遍歷數組a,其中i爲數組a的每個key,a[i]爲key對應的值;
使用awk命令獲取文本的某一行,某一列的技巧:shell
1)打印文件的第一列(域) : awk '{print $1}' filename 2)打印文件的前兩列(域) : awk '{print $1,$2}' filename 3)打印完第一列,而後打印第二列 : awk '{print $1 $2}' filename 4)打印文本文件的總行數 : awk 'END{print NR}' filename 5)打印文本第一行 :awk 'NR==1{print}' filename 6)打印文本第二行第一列 :sed -n "2, 1p" filename | awk 'print $1'
Awk取文件中的指定數據數組
[root@jump-v4 ~]# cat a.txt 123.122.123.12 12121212 121.2332.121.11 232323 255.255.255.255 21321 123.122.123.12 12121212 123.122.123.12 1212121er2 123.122.123.12 12121212eer 123.122.123.12 12121212ere 255.255.255.255 21321 121.2332.121.11 232323 255.255.255.255 21321 [root@jump-v4 ~]# cat a.txt|awk '{print $1}' 123.122.123.12 121.2332.121.11 255.255.255.255 123.122.123.12 123.122.123.12 123.122.123.12 123.122.123.12 255.255.255.255 121.2332.121.11 255.255.255.255 [root@jump-v4 ~]# cat a.txt|awk '{print $1}'|sort|uniq -c 2 121.2332.121.11 5 123.122.123.12 3 255.255.255.255 [root@jump-v4 ~]# cat a.txt|awk '{print $1}'|sort|uniq -c|awk '{print $2,$1}' 121.2332.121.11 2 123.122.123.12 5 255.255.255.255 3 [root@jump-v4 ~]# cat a.txt|awk '{print $1}'|sort|uniq -c|awk '{print $2,$1}'|sort -k2 -rn 123.122.123.12 5 255.255.255.255 3 121.2332.121.11 2
linux文件按大小來排序bash
[root@cdn ~]# ls -s | sort -k 1 -n 表示對第一個字段(即文件大小)按數值大小進行排序; 若是想倒序,能夠增長-r參數; sort命令可進行排序; -k參數表示對第幾個字段進行排序; ls -s:第一列顯示的是文件大小
定時刪除resin日誌的腳本,每小時刪除一次app
[root@cdn ~]# cat resin-log.sh #!/bin/bash cd /data/log/resin && find /data/log/resin \( -name "*jvm-app-0.log.*" -a ! -name "*.gz" \) -a -mmin +30 -exec gzip {} \; [root@cdn ~]# crontab -l 0 * * * * /bin/bash -x /root/resin-log.sh >/dev/null 2>&1
awk 獲取某些列的某些行(打印或不打印第幾行)jvm
NR==n 表示打印第n行 NR!=n 表示不打印第n行 1)取test.txt文件中的第1,2列,不打印第一行 [root@bz4citestap1014 app_zhibiao.sh]# cat test.txt wang 11 aa shi 22 bb kevin 33 cc grace 44 dd hui 55 ee [root@bz4citestap1014 app_zhibiao.sh]# awk 'NR!=1 {print $1,$2}' test.txt shi 22 kevin 33 grace 44 hui 55 2)取test.txt文件中的第3列的第2行 [root@bz4citestap1014 app_zhibiao.sh]# awk 'NR==2 {print $3}' test.txt bb
awk中的"匹配"與"不匹配"ui
~ 匹配正則 !~ 不匹配正則 == 等於 != 不等於 [root@kevin~]# cat test.txt afjdkj 80 lkdjfkja 8080 dfjj 80 jdsalfj 808080 jasj 80 jg 80 linuxidc 80 80 ajfkj asf 80 80 linuxidc wang bo kevin grace ha 80880 1) 打印上面test文件中第二列匹配80開頭並以80結束的行 [root@kevin~]# awk '{if($2~/^80$/)print}' test.txt afjdkj 80 dfjj 80 jasj 80 jg 80 linuxidc 80 asf 80 2)打印上面test文件中第二列中不匹配80開頭並以80結束的行 [root@kevin~]# awk '{if($2!~/^80$/)print}' test.txt lkdjfkja 8080 jdsalfj 808080 80 ajfkj 80 linuxidc wang bo kevin grace ha 80880 3)打印上面test文件中第二列是"bo"的行 [root@kevin~]# cat test.txt |awk '{if($2=="bo")print}' wang bo
AWK的內置變量(NF、NR、FNR、FS、OFS、RS、ORS)spa
NF 字段個數,(讀取的列數) NR 記錄數(行號),從1開始,新的文件延續上面的計數,新文件不從1開始 FNR 讀取文件的記錄數(行號),從1開始,新的文件從新從1開始計數 FS 輸入字段分隔符,默認是空格 OFS 輸出字段分隔符 默認也是空格 RS 輸入行分隔符,默認爲換行符 ORS 輸出行分隔符,默認爲換行符 示例文件test: [rootkevin ~]# cat test zhong guo ren is noce! beijing is a good city。 sheg as juf 88u kk halt:x:7:0:halt /sbin:/sbin/halt operator x 0:operator /root:/sbin/nologin 1)NF:讀取記錄的字段數(列數) [rootkevin ~]# awk -F" " '{print "字段數: " NF}' test 字段數: 5 字段數: 5 字段數: 5 字段數: 2 字段數: 4 如上,awk在讀取文件時,按行讀取,每一行的字段數(列數),賦值給內置變量NF,打印出來的就是每行的字段總數。 [rootkevin ~]# awk '{print $NF}' test noce! city。 kk /sbin:/sbin/halt /root:/sbin/nologin 若是有需求,只須要最後一列的數據,因爲每一行的列數不一,最後一列沒法指定固定的列數,可使用NF來表示列數$NF表示打印出等於總列數的那一列的數據, 顯而易見就是打印最後一列的數據。 2)NR:讀取文件的行數(在某些應用場景中能夠看成行號來使用) [rootkevin ~]# awk '{print "行號爲:" NR}' test 行號爲:1 行號爲:2 行號爲:3 行號爲:4 行號爲:5 如上,打印出讀取文件的行數,由於是按行讀取,在應用場景中,行數能夠等同於行號,用來輸出對應行的行號,NR 還能夠用做判斷輸出,以下簡單例子: [rootkevin ~]# awk '{if(NR>2)print "行號爲:" NR }' test 行號爲:3 行號爲:4 行號爲:5 3)FNR:讀取文件的行數,可是和"NR"不一樣的是當讀取的文件有兩個或兩個以上時,NR讀取完一個文件,行數繼續增長 而FNR從新從1開始記錄 [rootkevin ~]# cp test test1 [rootkevin ~]# awk '{print "NR:"NR "FNR:"FNR}' test test1 NR:1FNR:1 NR:2FNR:2 NR:3FNR:3 NR:4FNR:4 NR:5FNR:5 NR:6FNR:1 NR:7FNR:2 NR:8FNR:3 NR:9FNR:4 NR:10FNR:5 打印的兩列之間加上空格 [rootkevin ~]# awk '{print "NR:"NR " " "FNR:"FNR}' test test1 NR:1 FNR:1 NR:2 FNR:2 NR:3 FNR:3 NR:4 FNR:4 NR:5 FNR:5 NR:6 FNR:1 NR:7 FNR:2 NR:8 FNR:3 NR:9 FNR:4 NR:10 FNR:5 由上可知,NR從一開始一直增長,FNR每讀取到一個新的文件,行數從新從一開始增長。 有一個有趣的應用,比較兩個文件A,B是否一致,以A做爲參考,不一致的輸出行號 [rootkevin ~]# cat A a aa aaa 1 b bb bbb 2 c cc ccc d dd ddd 4 e ee eee 5 [rootkevin ~]# cat B a aa aaa 1 b bb bbb 2 c cc ccc 3 d dd ddd 4 e ee eee 5 [rootkevin ~]# awk '{if(NR==FNR){arry[NR]=$0}else{if(arry[FNR]!=$0){print FNR}}}' A B 3 4)FS:輸入字段分割符,默認是以空格爲分隔符,在平常中經常文本里面不都以空格分隔,此時就要指定分割符來格式化輸入。 [rootkevin ~]# cat test2 a,b,c 1,2,3 aa,dd,ee [rootkevin ~]# awk '{print $1}' test2 a,b,c 1,2,3 aa,dd,ee [rootkevin ~]# awk 'BEGIN{FS=","}{print $1}' test2 a 1 aa 使用-F參數也能夠 [rootkevin ~]# awk -F"," '{print $1}' test2 a 1 aa 5)OFS:輸出字段分割符,默認爲空格,若是讀進來的數據是以空格分割,爲了需求可能要求輸出是以"-"分割,可使用OFS進行格式化輸出。 [rootkevin ~]# cat test3 a aa aaa 1 b bb bbb 2 c cc ccc d dd ddd 4 e ee eee 5 [rootkevin ~]# awk 'BEGIN{FS=" ";OFS="--"}{print $1,$2,$3}' test3 a--aa--aaa b--bb--bbb c--cc--ccc d--dd--ddd e--ee--eee [rootkevin ~]# awk -vOFS="|" 'NF+=0' test3 a|aa|aaa|1 b|bb|bbb|2 c|cc|ccc d|dd|ddd|4 e|ee|eee|5 [rootkevin ~]# cat test6 172.10.10.10 172.10.10.11 172.10.10.12 172.10.10.13 172.10.10.14 [rootkevin ~]# awk 'BEGIN{FS=".";OFS="--"}{print $1,$2,$3}' test6 172--10--10 172--10--10 172--10--10 172--10--10 172--10--10 6)RS:輸入行分隔符,判斷輸入部分的行的起始位置,默認是換行符 [rootkevin ~]# cat test4 a,b,c d,e,f g,h,i j,k,l [rootkevin ~]# awk 'BEGIN{RS=","}{print}' test4 a b c d e f g h i j k l [rootkevin ~]# 這裏說明一下,RS=","將以,爲分割看成一行,即a被看成一行,b也被看成一行,可是細心的會發現和d之間是沒有","的爲何也看成一行了呢, 是由於輸入中c後面還有一個換行符\n 即,輸入應該是a,b,c\n只不過\n咱們看不到,輸入中,a一行,b一行,c\nd一行可是輸出的時候系統會將\n視爲換行符, 因此看上去c和d是兩行,其實是一行。 7)ORS:輸出行分割符,默認的是換行符,它的機制和OFS機制同樣,對輸出格式有要求時,能夠進行格式化輸出 [rootkevin ~]# cat test5 1 22,aa:bb haha,hehe aa bb cc [rootkevin ~]# awk 'BEGIN{ORS=" "}{print}' test5 1 22,aa:bb haha,hehe aa bb cc [rootkevin ~]# cat test6 172.10.10.10 172.10.10.11 172.10.10.12 172.10.10.13 172.10.10.14 [rootkevin ~]# awk 'BEGIN{ORS=","}{print}' test6 172.10.10.10,172.10.10.11,172.10.10.12,172.10.10.13,172.10.10.14, 也能夠以下實現以","隔開放在一行 [rootkevin ~]# cat test6|xargs 172.10.10.10 172.10.10.11 172.10.10.12 172.10.10.13 172.10.10.14 [rootkevin ~]# cat test6|xargs|sed 's/ /,/g' 172.10.10.10,172.10.10.11,172.10.10.12,172.10.10.13,172.10.10.14