1 awk:文本和數(shù)據(jù)處理工具
awk擅長于對數(shù)據(jù)進行分析并生成報告,簡單來說awk就是把文件逐行的讀入,以空格為默認(rèn)分隔符將每行切片,切開的部分再進行各種分析處理。
使用方法:awk '{pattern + action}' {filenames} ?
其中pattern 表示awk 在數(shù)據(jù)中查找的內(nèi)容,而action是在找到匹配內(nèi)容時所執(zhí)行的一系列命令。花括號({})不需要在程序中始終出現(xiàn),但它們用于根據(jù)特定的模式對一系列指令進行分組。pattern就是要表示的正則表達式,用斜杠括起來。準(zhǔn)備實例操作文件:netstat ?-t >> netstat.txt
1.1 打印輸出:print,格式化打印輸出:printf
awk '{print$1, $4}' netstat.txt
awk '{printf "%-8s %-8s %-8s %-18s %-22s %-15s\n",$1,$2,$3,$4,$5,$6}' netstat.txt
1.2 過濾記錄:awk '$3==0 && $6=="LISTEN"' netstat.txt
其中的“==”為比較運算符。其他比較運算符:!=,>, <, >=, <=
awk '$3>0 {print $0}' netstat.txt
加入表頭:內(nèi)建變量NR
awk '$3==0 && $6=="LISTEN" || NR==1 ' netstat.txt
再加上格式化輸出 ? ? ? ? ? ? ? ? ? ??
awk '$3 ==0 && $6=="LISTEN" || NR==1 {printf "%-20s %-20s %s\n",$4,$5,$6}' netstat.txt
ps:awk的內(nèi)建變量
| $0 | 當(dāng)前記錄(這個變量中存放著整個行的內(nèi)容) |
| $1~$n | 當(dāng)前記錄的第n個字段,字段間由FS分隔 |
| FS | 輸入字段分隔符默認(rèn)是空格或Tab |
| NF | 當(dāng)前記錄中的字段個數(shù),就是有多少列 |
| NR | 已經(jīng)讀出的記錄數(shù),就是行號,從1開始,如果有多個文件話,這個值也是不斷累加中。 |
| FNR | 當(dāng)前記錄數(shù),與NR不同的是,這個值會是各個文件自己的行號 |
| RS | 輸入的記錄分隔符,默認(rèn)為換行符 |
| OFS | 輸出字段分隔符,默認(rèn)也是空格 |
| ORS | 輸出的記錄分隔符,默認(rèn)為換行符 |
| FILENAME | 當(dāng)前輸入文件的名字 |
輸出行號:awk '$3 ==0 && $6=="ESTABLISHED"|| NR==1 {printf "%02s %s %-20s %-20s %s\n",NR, FNR,$4,$5,$6}' netstat.txt
指定分隔符:awk 'BEGIN{FS=":"} {print $1,$3,$6}' /etc/passwd
或者awk -F: '{print $1,$3,$6}' /etc/passwd
以\t作為分隔符輸出:awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd
1.3 字符串匹配:~表示匹配模式開始,正則表達式匹配。
awk '$6 ~ /TIME/ || NR ==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
awk '$6 ~ /ESTABLISHED/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
awk '/LISTEN/' netstat.txt
使用“/TIME|ESTABLISHED/” 來匹配TIME 或者ESTABLISHED :
awk '$6 ~ /FIN|TIME/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
模式取反:!~
awk '$6 !~ /TIME/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt
或者awk '!/WAIT/' netstat.txt
1.4 拆分文件:使用數(shù)據(jù)流重定向”>”
awk 'NR!=1 {print > $6}' netstat.txt ? ? ?NR!=1表示不處理表頭
把指定的列輸出到文件: ?awk 'NR!=1{print $4,$5 > $6}' netstat.txt
使用程序流進行條件拆分:if else
awk 'NR!=1{if($6 ~ /TIME|ESTABLISHED/) print > "1.txt";
else if($6 ~ /LISTEN/) print > "2.txt";
else print > "3.txt"}' netstat.txt
1.5 統(tǒng)計
計算所有的C文件,CPP文件和H文件的文件大小總和:
ls -l *.cpp *.c*.h | awk '{sum+=$5} END {print sum}'
統(tǒng)計各個connection狀態(tài)的用法:使用數(shù)組
awk 'NR!=1{a[$6]++;} END {for (i in a) print i ", " a[i];}' netstat.txt
統(tǒng)計每個用戶的進程的占了多少內(nèi)存:
ps aux| awk 'NR!=1{a[$1]+=$6;} END { for(i ina) print i ", " a[i]"KB";}'
數(shù)組:因為awk中數(shù)組的下標(biāo)可以是數(shù)字和字母,數(shù)組的下標(biāo)通常被稱為關(guān)鍵字(key)。值和關(guān)鍵字都存儲在內(nèi)部的一張針對key/value應(yīng)用hash的表格里。由于hash不是順序存儲,因此在顯示數(shù)組內(nèi)容時會發(fā)現(xiàn),它們并不是按照你預(yù)料的順序顯示出來的。數(shù)組和變量一樣,都是在使用時自動創(chuàng)建的,awk也同樣會自動判斷其存儲的是數(shù)字還是字符串。一般而言,awk中的數(shù)組用來從記錄中收集信息,可以用于計算總和、統(tǒng)計單詞以及跟蹤模板被匹配的次數(shù)等等。
1.6 使用腳本進行文本、數(shù)據(jù)處理
BEGIN、END關(guān)鍵字:BEGIN表示處理所有行之前的標(biāo)識,END表示處理完所有行后的標(biāo)識,具體語法:
BEGIN{ 這里面放的是執(zhí)行前的語句}
END {這里面放的是處理完所有的行后要執(zhí)行的語句}
{這里面放的是處理每一行時要執(zhí)行的語句}
實例操作文件: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
}
執(zhí)行:awk -f cal.awk score.txt
1.7 變量聲明和環(huán)境變量:使用-v參數(shù)進行變量聲明,ENVIRON關(guān)鍵字表示環(huán)境變量
$ x=5
$ y=10
$ export y ? ? ? ? ? ? ? ? ? ? ? ? ?#y被export為環(huán)境變量
$ echo $x $y
5 ? ?10
$awk -v val=$x '{print $1, $2, $3, $4+val, $5+ENVIRON["y"]}' OFS="\t" score.txt
2 sed:流編輯器
stream editor,流編輯器,用程序的方式來編輯文本,正則表達式進行模式匹配。sed本身是一個管道命令,可以分析standard input,也可以將數(shù)據(jù)進行替換、刪除、新增、頡取特定行等功能。
演示文本:catpets.txt
This is my cat
my cat's name is betty
This is my dog
my dog's name is frank
This is my fish
my fish's name is george
This is my goat
my goat's name is adam
使用:sed [-nefr] action
action:-i直接修改讀取的檔案內(nèi)容,而不是由屏幕輸出,-r表示支持延伸型正則表達式的語法。
動作說明:[n1[,n2]] function n1,n2表示要選擇的行數(shù),function包括:
a-新增,c-取代,d-刪除,i-插入,p-打印,s-取代(可以直接進行取代的工作,例如 1,20s/old/new/g)
2.1 用s命令進行替換
my字符串替換成Rango Chen’s
sed “s/my/Rango Chen's/g” pets.txt
ps:如果使用單引號,則無法通過\'來轉(zhuǎn)義。該命令并沒有對文件內(nèi)容進行更改,只是把處理過后的內(nèi)容輸出,如果你要寫回文件,你可以使用重定向:sed "s/my/Rango Chen's/g" pets.txt >Chen_pets.txt,或者使用-i選項:sed -i “s/my/Rango Chen's/g” pets.txt
s表示替換動作,/g表示一行上的替換所有的匹配。
在每一行最前面加上#:sed 's/^/#/g' pets.txt ? ? ? ?
在每一行的末尾加上---:sed 's/$/ --- /g' pets.txt ? ?
基礎(chǔ)的正則表示法特殊字符:
^ 表示一行的開頭。如:/^#/ 以#開頭的匹配。
$ 表示一行的結(jié)尾。如:/}$/ 以}結(jié)尾的匹配。
\< 表示詞首。如\<abc 表示以abc 為首的詞。
\> 表示詞尾。如 abc\> 表示以abc 結(jié)尾的詞。
\ ?將特殊字符進行轉(zhuǎn)義,還原其本身意義:grep -n ?\' pets.txt 搜尋含有單引號'的那一行。
. 表示任何單個字符。
* 表示某個字符出現(xiàn)了0次或多次。
[ ] 字符集合。如:[abc]表示匹配a或b或c,還有[a-zA-Z]表示匹配所有的26個字符。如果其中有^表示取反,如[^a]表示非a的字符
\{n,m\} 連續(xù)n到m個的“前一個RE字符” grep -n 'go\{2,3\}g' 1.txt ? 在g與g之間有2到3個o存在的字符串,亦即(goog)(gooog)
去掉某html中的tags:html.txt:
? ?<b>This</b>is what <span style="text-decoration:underline;">I</span> meant. ?Understand?
sed 's/<[^>]*>//g' html.txt
只替換第3到第6行的文本:sed "3,6s/my/your/g" pets.txt
只替換第3行的文本:sed "3s/my/your/g" pets.txt
只替換每一行的第一個s:sed 's/s/S/1' my.txt ? 1表示第一個
只替換每一行的第二個s:sed 's/s/S/2' my.txt ? ?2表示第二個
只替換第一行的第3個以后的s:sed 's/s/S/3g' my.txt
2.2 多個匹配
一次替換多個模式,每個模式之間用;進行間隔:sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt
上面的命令等價于:sed -e'1,3s/my/your/g' -e '3,$s/This/That/g' my.txt
使用&來當(dāng)做被匹配的變量,加入一些字符:sed 's/my/[&]/g' my.txt
此命令相當(dāng)于在my兩邊加上[]
2.3 圓括號匹配
圓括號括起來的正則表達式所匹配的字符串會可以當(dāng)成變量來使用,sed中使用的是\1,\2…
sed 's/This is my [,]?,.*is .?/\1:\2/g' my.txt
cat:betty
dog:frank
fish:george
goat:adam
2.4 基本知識點
1)Pattern Space:關(guān)于參數(shù)-n,表示取消默認(rèn)輸出,相當(dāng)于--quiet,--silent。在sed處理文件的時候,每一行都被保存在一個叫模式空間的臨時緩沖區(qū)中,除非行被刪除或者輸出被取消,否則所有被處理的行都將打印在屏幕上。接著模式空間被清空,并存入新的一行等待處理。
2)Address:[address[,address]][!]{cmd},其中的!表示匹配成功后是否執(zhí)行命令,address可以是一個數(shù)字,也可以是一個模式,可以通過逗號分隔兩個address表示兩個address的區(qū)間。
3)命令打包:cmd可以是多個,它們可以用分號分開,可以用大括號括起來作為嵌套命令
對3行到第6行,匹配/This/成功后,再匹配/fish/,成功后執(zhí)行d命令:
sed '3,6 {/This/{/fish/d}}' pets.txt
從第一行到最后一行,如果匹配到This,則刪除之;如果前面有空格,則去除空格:
sed '1,${/This/d ; s/^ *//g}' pets.txt
4)HoldSpace:保持空間
g:將hold space中的內(nèi)容拷貝到pattern space中,原來pattern space里的內(nèi)容清除
G:將hold space中的內(nèi)容append到pattern space\n后
h:將pattern space中的內(nèi)容拷貝到hold space中,原來的hold space里的內(nèi)容被清除
H:將pattern space中的內(nèi)容append到hold space\n后
x:交換pattern space和hold space的內(nèi)容
sed -e '/test/h' -e '$G‘ ?example:在這個例子里,匹配test的行被找到后,將存入模式空間,h命令將其復(fù)制并存入一個稱為保持緩存區(qū)的特殊緩沖區(qū)內(nèi)。第二條語句的意思是,當(dāng)?shù)竭_最后一行后,G命令取出保持緩沖區(qū)的行,然后把它放回模式空間中,且追加到現(xiàn)在已經(jīng)存在于模式空間中的行的末尾。在這個例子中就是追加到最后一行。簡單來說,任何包含test的行都被復(fù)制并追加到該文件的末尾。
sed -e '/test/h' -e '/check/x' example:互換模式空間和保持緩沖區(qū)的內(nèi)容。也就是把包含test與check的行互換。
5)執(zhí)行sed腳本:sed -f test.sed
Sed對于腳本中輸入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多個命令,要用分號分隔。以#開頭的行為注釋行,且不能跨行。
ps: 去除空白行:sed '/^ *$/d' file
3 sort:文本內(nèi)容排序
語 法:sort [-bcdfimMnr] [-o<輸出文件>] [-t<分隔字符>] [+<起始欄位>-<結(jié)束欄位>] [--help] [--verison] [文件]
參 數(shù):
-b ? ?忽略每行前面開始出的空格字符。
-c ? ?檢查文件是否已經(jīng)按照順序排序。
-d ? ?排序時,處理英文字母、數(shù)字及空格字符外,忽略其他的字符。
-f ? ?排序時,將小寫字母視為大寫字母。
-i ? ?排序時,除了040至176之間的ASCII字符外,忽略其他的字符。
-m ? ?將幾個排序好的文件進行合并。
-M ? ?將前面3個字母依照月份的縮寫進行排序。
-n ? ?依照數(shù)值的大小排序。
-o<輸出文件> ? ?將排序后的結(jié)果存入指定的文件。
-r ? ?以相反的順序來排序。
-t<分隔字符> ? ?指定排序時所用的欄位分隔字符。
+<起始欄位>-<結(jié)束欄位> ? ?以指定的欄位來排序,范圍由起始欄位到結(jié)束欄位的前一欄位。
--help ? ?顯示幫助。
--version ? ?顯示版本信息
4 uniq:Filter adjacent matching lines from INPUT (or standard input), writingto OUTPUT (or standard output)
顯示唯一的行,對于那些連續(xù)重復(fù)的行只顯示一次,以及計數(shù)重復(fù)的行
uniq:不加任何參數(shù)表示匹配第一次出現(xiàn)的那行
uniq -c:顯示重復(fù)的行的行數(shù)
uniq -u:僅顯示文件中沒有連續(xù)出現(xiàn)的行,唯一行
uniq -d:僅顯示文件中連續(xù)重復(fù)出現(xiàn)的行。
5 cut:片段頡取工具,可以從一個文本文件或者文本流中提取文本列
5.1 命令用法
cut -b list [-n] [file ...] ? ? ? ?
cut -c list [file ...]
cut -f list [-d delim][-s][file ...]
-b、-c、-f分別表示字節(jié)、字符、字段(即byte、character、field);list表示-b,-c,-f操作范圍,-n表示具體數(shù)字,with -b: don’t split multibyte characters;file表示的自然是要操作的文本文件的名稱;delim(英文全寫:delimiter)表示分隔符,默認(rèn)情況下為TAB;-s表示不包括那些不含分隔符的行(這樣有利于去掉注釋和標(biāo)題)。--output-delimiter=字符串,使用指定的字符串作為輸出分界符,默認(rèn)采用輸入的分界符。上面三種方式中,表示從指定的范圍中提取字節(jié)(-b)、或字符(-c)、或字段(-f)。
LIST的范圍:
| N | 只有第N項 |
| N- | 從第N項一直到行尾 |
| N-M | 從第N項到第M項(包括M) |
| -M | 從一行的開始到第M項(包括M) |
| - | 從一行的開始到結(jié)束的所有項 |
5.2 用法實例
頡取/etc/passwd文件中的前十五個用戶名:
cut -f1 -d: /etc/passwd | head -15
頡取/etc/passwd文件每一行前十個字節(jié)的內(nèi)容:
cut -b 1-10 /etc/passwd
頡取該文件每一行第1,4,7個字節(jié)的內(nèi)容:
cut -b 1,4,7 /etc/passwd
將/etc/passwd的分隔符換成“|”輸出:
cut -d: -f 1- -s --output-delimiter=”|” /etc/passwd
6 grep:頡取具有特定信息的行,逐行操作
用法:grep [-acinv] [--color=auto] '搜尋字符串' filename
-a : ? ?將binary檔案以text 檔案的方式搜尋數(shù)據(jù)
-c: ? ?計算找到'搜尋字符串'的次數(shù)
-i: ? ?忽略大小寫的不同,所以大小寫視為相同
-n : ? ?順便輸出行號
-v : ? ?反向選擇,亦即顯示出沒有'搜尋字符串'內(nèi)容的那一行!
--color=auto: ? ?可以將找到的關(guān)鍵詞部分加上顏色的顯示!
7 wc:wordcount,printnewline, word, and byte counts for each file
用法:wc [-lwmc]
-l : ? ?僅列出行; ? ?
-w : ? ?僅列出多少字(英文單字);?
-m : ? ?多少字符;
-c: ? ?多少字節(jié)
不加任何參數(shù)表示全部列出。
實例:/etc/man.config 里面有多少相關(guān)字、行、字符數(shù):
cat /etc/man.config | wc?
轉(zhuǎn)自:http://rangochen.blog.51cto.com/2445286/1373476
總結(jié)
以上是生活随笔為你收集整理的Linux基础篇之文本、数据流处理命令(sed uniq grep awk wc)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。