天天看點

linux 指令 之 sed awk

coolshell是個很不錯的小站,請大家多關注

awk

awk [options] 'script' files

下面我們較長的描述script區域

關鍵字

{} 代表對每一行進行處理的語句

BEGIN{} 代表對每一行進行處理前執行的語句

END{} 代表對每一行進行處理後執行的語句

$ cat score.txt

Marry 2143 78 84 77

Jack 2321 66 78 45

Tom 2122 48 77 71

Mike 2537 87 97 95

Bob 2415 40 57 62

cat cal.awk

#!/bin/awk -f

#運作前

BEGIN {

math = 0

english = 0

computer = 0

printf "NAME NO. MATH ENGLISH COMPUTER TOTAL\n"

printf "---------------------------------------------\n"

}

#運作中

{

math+=$3

english+=$4

computer+=$5

printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5

}

#運作後

END {

printf "---------------------------------------------\n"

printf " TOTAL:%10d %8d %8d \n", math, english, computer

printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR

}

awk -f cal.awk score.txt

語句

1.列印 '{print $1,$2 ...}'

列印檔案中每一行的第一列和第二列;其中$1代表第一列,$2代表第二列,以此類推,$0代表每一列,即一整行 

2.格式化輸出 'printf "%-20s %-20s %s\n",$4,$5,$6 '
3.過濾 '$3==0 && $6=="LISTEN" '

awk支援比較運算符 == != > < >= <=; 字元串可以使用 “ ”

第二種過濾是 字元串比對 ~ / pattern  / pattern比對時可以 使用 | ,取反 ' !/pattern/ '

'$6 ~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' 

當然也可以 在外面比對  awk '/LISTEN/ ' filename

4.拆分檔案 awk 'NR!=1{print > $6} '

NR!=1表示排除第一行,然後把第六列相同的值儲存到命名為該值的檔案中

複雜些加上條件語句

'NR!=1{

if($6 ~ /TIME|ESTABLISHED/) print > "1.txt";

else if($6 ~ /LISTEN/) print > "2.txt";

else print > "3.txt"     }'

5.内置變量
$0 目前記錄(這個變量中存放着整個行的内容)
$1~$n 目前記錄的第n個字段,字段間由FS分隔
FS 輸入字段分隔符 預設是空格或Tab
NF 目前記錄中的字段個數,就是有多少列
NR 已經讀出的記錄數,就是行号,從1開始,如果有多個檔案話,這個值也是不斷累加中。
FNR 目前記錄數,與NR不同的是,這個值會是各個檔案自己的行号
RS 輸入的記錄分隔符, 預設為換行符
OFS 輸出字段分隔符, 預設也是空格
ORS 輸出的記錄分隔符,預設為換行符
FILENAME 目前輸入檔案的名字

(1).FS & OFS 分隔符

awk  'BEGIN{FS=":"} {print $1,$3,$6}' /etc/passwd 使用:作為分隔符,而不是space

也可以awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd,其中想要制定多個分隔符 可以使用-F ' [;:] '

(2).NR & FNR 分隔符

如果使用過濾條件,有想要列印出第一行的所有内容,可以使用NR==1;FNR表示自己的行号

awk '$3==0 && $6=="ESTABLISHED" || NR==1 {printf "%02s %s %-20s %-20s %s\n",NR, FNR, $4,$5,$6}' netstat.txt

awk程式設計

1.變量指派

可以直接使用變量,預設初始化為0,妥當做法是顯示初始化

2.計算運算符 + - * / 甚至還支援 += ++ 等
3.條件語句,循環語句

if (expression) {

statement1;

} else if (expression1) {

statement2;

} else {

statement3;

}

awk中的循環語句同樣借鑒于C語言,支援while、do/while、for、break、continue,這些關鍵字的語義和C語言中的語義完全相同。

'NR!=1{a[$6]++;} END {for (i in a) print i ", " a[i];}'

檢視每個程序占用多少記憶體 ps aux | awk 'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'

8.length 

awk 'length>80' file

9.使用環境變量

options使用-v  在script中使用 ENVIRON["value name"] 代表環境變量标簽

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

sed

最近懶了,來來來,把sed補上

玩sed需要熟練操作正規表達式

sed的很多操作方式非常類似于vim

sed [options] "commands" filename

老規矩,先看commands

指令

替換

和vim一樣

sed “s/source/dest/g" filename

如果想要使用單引号,最好外包雙引号,而且使用雙引号可以哦那個過\ 轉意其他字元‘

1)簡單正規表達式

^開頭 ^s 比對以s開頭

$結尾 s$比對以s結尾

\< 詞頭 \<s 以s開頭的詞

\> 詞尾 \>s 以s結尾的詞

. 表示任何單個字元

* 表示某個字元出現了0次或多次 ? 表示某個字元出現了1次或多次

[] 字元集合 [abc] 表示比對 a 或者 b 或者 c ;如果 [^a] 表示a取反,除了a之外的字元

可以是用正規表達式來做字元替換,下面介紹寫例子

2) 替換的文本寫回到源檔案

兩種辦法  1.使用管道  sed “commands" filename > filename

2.使用options -i sed "commands" filename 即可

3)在每行開頭加入 #

sed "s/^/#/g" filename

4) 去掉html的tags

sed 's/ < [^>] * > / / g " filename

5)替換特定行和特定列

sed "3,$ s/source/dest/g" filename 替換第三行到最後一行所有

sed "3,$ s/source/dest/1" filename 隻替換第二個符合source的字段

sed "1,3 s/source/dest/3g" filename 替換第一行到第三行的每一行中第三個到最後一個符合source的字段

6)多個比對

兩種辦法。1.在commands中使用分号; sed " s/source1/dest1/g ; s/source2/dest2/g " filename

2.使用options -e sed -e "s/source1/dest1/g" -e "s/source2/dest2/g" filename

7)&符号

可以使用&值代前面的pattern

sed "s/pattern/[&]/g" filename 這樣就在所有patter左右加了[]

8)圓括号比對

比對出來的pattern的第一個用 \1 指代,以此類推

sed “s/ pattern1, pattern2 / \1:\2/g " filename

其他指令

分為n指令,c,p,a&i,d指令等

1)N指令,把下一行的内容納入緩沖區當作比對

 sed 'N;s/\n/,/' pets.txt 将兩行合并為一行,并且中間使用,分割

2)插入 a & i

sed "$ a test " filename 後面插入

sed "$ i test " filename  前面插入

也可以使用比對

sed "/my/a ----" my.txt

3)替換c指令

sed "2 c test" my.txt

sed "/fish/ c test" my.txt

4) 删除d指令

同理,,,

5)列印p指令

高階sed待續,哈哈

http://sebug.net/paper/books/awk/

http://coolshell.cn/articles/9070.html 

http://coolshell.cn/articles/9104.html

繼續閱讀