使用awk和sed獲取檔案奇偶數行的方法總結

散盡浮華發表於2019-03-16

 

測試檔案test.file

[root@localhost ~]# cat test.file
111111111111111
222222222222222
333333333333333
444444444444444
555555555555555
666666666666666
777777777777777
888888888888888
999999999999999
1010101010101010

1) 列印奇數行的方法

[root@localhost ~]# sed -n '1~2p' test.file
111111111111111
333333333333333
555555555555555
777777777777777
999999999999999
 
[root@localhost ~]# sed -n 'p;n' test.file
111111111111111
333333333333333
555555555555555
777777777777777
999999999999999

[root@localhost ~]# sed -n '1,$p;n' test.file
111111111111111
333333333333333
555555555555555
777777777777777
999999999999999

[root@localhost ~]# sed '2~2d' test.file
111111111111111
333333333333333
555555555555555
777777777777777
999999999999999

[root@localhost ~]# awk 'NR%2==1' test.file 
111111111111111
333333333333333
555555555555555
777777777777777
999999999999999
 
[root@localhost ~]# awk 'NR%2' test.file
111111111111111
333333333333333
555555555555555
777777777777777
999999999999999
 
[root@localhost ~]# awk 'i=!i' test.file
111111111111111
333333333333333
555555555555555
777777777777777
999999999999999

2) 列印偶數行的方法

[root@localhost ~]# sed -n '2~2p' test.file       
222222222222222
444444444444444
666666666666666
888888888888888
1010101010101010
 
[root@localhost ~]# sed -n 'n;p' test.file
222222222222222
444444444444444
666666666666666
888888888888888
1010101010101010

[root@localhost ~]# sed -n '1,$n;p' test.file
222222222222222
444444444444444
666666666666666
888888888888888
1010101010101010

[root@localhost ~]# sed '1~2d' test.file
222222222222222
444444444444444
666666666666666
888888888888888
1010101010101010

[root@localhost ~]# awk 'NR%2==0' test.file
222222222222222
444444444444444
666666666666666
888888888888888
1010101010101010
 
[root@localhost ~]# awk '!(NR%2)' test.file
222222222222222
444444444444444
666666666666666
888888888888888
1010101010101010
 
[root@localhost ~]# awk '!(i=!i)' test.file
222222222222222
444444444444444
666666666666666
888888888888888
1010101010101010

列印奇偶行的方法總結

sed -n '1~2p' test.file   列印奇數行
sed -n '2~2p' test.file   列印偶數行

sed -n 'p;n' test.file    列印奇數行
sed -n 'n;p' test.file    列印偶數行

sed -n '1,$p;n' test.file 列印奇數行
sed -n '1,$n;p' test.file 列印偶數行

sed '2~2d' test.file      列印奇數行
sed '1~2d' test.file      列印偶數行

awk 'NR%2==1' test.file   列印奇數行
awk 'NR%2==0' test.file   列印偶數行

awk 'NR%2' test.file      列印奇數行
awk '!(NR%2)' test.file   列印偶數行

awk 'i=!i' test.file      列印奇數行
awk '!(i=!i)' test.file   列印偶數行

                                                            其他相關正則取值說明                                                       

1) 列印行號和內容
[root@localhost ~]# awk '{print NR":"$0}' test.file 
1:111111111111111
2:222222222222222
3:333333333333333
4:444444444444444
5:555555555555555
6:666666666666666
7:777777777777777
8:888888888888888
9:999999999999999
10:1010101010101010

2) 每行間加一個空行
[root@localhost ~]# awk '1; { print "" }' test.file
111111111111111

222222222222222

333333333333333

444444444444444

555555555555555

666666666666666

777777777777777

888888888888888

999999999999999

1010101010101010


[root@localhost ~]# awk '1 { print } { print "" }' test.file 
111111111111111

222222222222222

333333333333333

444444444444444

555555555555555

666666666666666

777777777777777

888888888888888

999999999999999

1010101010101010

[root@localhost ~]# awk '{ print } { print "" }' test.file
111111111111111

222222222222222

333333333333333

444444444444444

555555555555555

666666666666666

777777777777777

888888888888888

999999999999999

1010101010101010

[root@localhost ~]# awk 'BEGIN { ORS="\n\n" }; 1' test.file
111111111111111

222222222222222

333333333333333

444444444444444

555555555555555

666666666666666

777777777777777

888888888888888

999999999999999

1010101010101010

3) 僅輸出非空行,並每行間在加一個空行
# awk 'NF { print $0 "\n" }' test.file
NF表示當前行的欄位數,$0表示當前行,最後再加一個換行

4) 雙倍行距;沒行間兩個空行
預設輸出後會換行的,輸出\n,則會輸出兩個空白行
[root@localhost ~]# awk '1; { print "\n" }' test.file 
111111111111111


222222222222222


333333333333333


444444444444444


555555555555555


666666666666666


777777777777777


888888888888888


999999999999999


1010101010101010


[root@localhost ~]# awk '{ print; print "\n" }' test.file
111111111111111


222222222222222


333333333333333


444444444444444


555555555555555


666666666666666


777777777777777


888888888888888


999999999999999


1010101010101010


5) 顯示當前行在所在檔案中的行號
FNR,表示當前行在檔案中的行號
[root@localhost ~]# awk '{ print FNR "\t" $0 }' test.file
1       111111111111111
2       222222222222222
3       333333333333333
4       444444444444444
5       555555555555555
6       666666666666666
7       777777777777777
8       888888888888888
9       999999999999999
10      1010101010101010

6) 顯示當前行在本次處理過程中的行號
NR,表示當前行在本次處理過程中的行號
[root@localhost ~]# awk '{ print NR "\t" $0 }' test.file
1       111111111111111
2       222222222222222
3       333333333333333
4       444444444444444
5       555555555555555
6       666666666666666
7       777777777777777
8       888888888888888
9       999999999999999
10      1010101010101010

為啥有FNR和NR的差別呢?效果不都是一樣麼? 
如果使用兩個檔案filname1.ext  filname2.ext,則就會看到差別了。
原來:FNR,是每個檔案中的,換了一個檔案,會歸零;而NR則每個檔案會累加起來的

7) 使用簡單樣式來輸出
下面表示"行號佔用5位,不足補空格"
[root@localhost ~]# awk '{ printf("] : %s\n", NR, $0) }' test.file 
] : 1
] : 2
] : 3
] : 4
] : 5
] : 6
] : 7
] : 8
] : 9
] : 10

8) 顯示非空行
# awk 'NF { $0=++a " :" $0 }; { print }'   test.file
NF前面說了,表示當前行的行號,此處用他作為條件,如果是空行,則NF為0,跳過;否則,用動態變數a儲存非空行的數目

9) 計算行數:效果類似wc -l
END表示每行都處理完了後,在執行,此時NR就是最後一行的行號,也就是總的行數了。
#awk 'END { print NR }'   test.file    

10) 計算每一行的和
s用作每行和的累加,從1到NF(每行總的欄位數),依次累加
# awk '{ s = 0; for (i = 1; i <= NF; i++) s = s+$i; print s }'   test.file

11)  計算檔案中所有欄位的和
s用作總和的累加,每行都處理完成了,再輸出s;注意和10對比,此處沒有每行清零,所以累加了。沒有設定的變數,預設為空,
但是會根據上下文數值計算情況自動變為0
# awk '{ for (i = 1; i <= NF; i++) s = s+$i }; END { print s }'   test.file

12) 將每個欄位用其絕對值代替
$i表示當前行中的欄位,$0表示當前行,可以改變$i的值
# awk '{ for (i = 1; i <= NF; i++) if ($i < 0) $i = -$i; print }'  test.file

13)  計算檔案中總的欄位和(例如計算單詞數)
# awk '{ total = total + NF }; END { print total }'  test.file

14) 計算匹配指定資訊的總行數
# awk '/Linux/ { n++ }; END { print n+0 }'  test.file

15) 找到檔案中每行第一個欄位中,最大的數,以及其所在的行
用max儲存最大的數,maxline儲存最大數所在的行,並在最後輸出
# awk '$1 > max { max=$1; maxline=$0 }; END { print max, maxline }'  test.file

16) 顯示當前行的欄位數,並輸出當前行
# awk '{ print NF ":" $0 } '  test.file

17) 顯示每行最後一個欄位的內容
# awk '{ print $NF }'  test.file   #NF表示當前行的欄位數,例如為3,則$NF,就是$3,也就是第三個欄位了

18) 顯示最後一行的最後一個欄位
每行處理沒有輸出,盡在最後輸出,field作為每行的最後一行的暫存變數
# awk '{ field = $NF }; END { print field }'  test.file

19) 顯示欄位數小於4的行
# awk 'NF < 4'  test.file   

20) 顯示每行的最後一個欄位小於4的行
# awk '$NF < 4'  test.file  

                                                            shell指令碼,實現奇數行等於偶數行                                                    

[root@localhost ~]# cat kevin.file
aa
11
bb
22
cc
33
dd
44

使用awk命令可以這樣實現:
[root@localhost ~]# awk 'NR%2==0{print a"="$0}{a=$0}' kevin.file
aa=11
bb=22
cc=33
dd=44

使用shell指令碼可以這樣實現:
[root@localhost ~]# cat kevin.sh 
#!/bin/bash
n=0
for i in $(cat /root/kevin.file)
do
  n=$(($n+1))
    [ $((n%2)) -eq 1 ] && echo -n $i=
    [ $((n%2)) -eq 0 ] && echo $i
done

[root@localhost ~]# sh kevin.sh
aa=11
bb=22
cc=33
dd=44

相關文章