shell 正則表達式和grep awk find sed sort uniq cut
一,grep
1,基礎參數
grep-[acinv]'搜索內容串'filename
-a以文本文件方式搜索
-c計算找到的符合行的次數
-i忽略大小寫
-n順便輸出行號
-v反向選擇,即找沒有搜索字符串的行
[root@test3 ~]# cat Travel.doc Travel is a good way to refresh and broaden our horizon. During your travel, you can turn off your cellphone and keep far from the Internet. You can forget your work, your study or your family, and just enjoy the leisure time. From the moment when you start your journey, all the trifles should be locked at your house. During the travel, you can kill your time slowly to have a good rest, and you can contact with different people. They may be a window for you to know a different world. Meet various people, experience things, which make your world bigger. You just clean up your entire mind and you can get the true meaning of travel. 找出有The的行,並打印行號 [root@test3 ~]# grep -n "The" Travel.doc 5:They may be a window for you to know a different world. 搜索沒有The的行 [root@test3 ~]# grep -vn "The" Travel.doc 1:Travel is a good way to refresh and broaden our horizon. 2:During your travel, you can turn off your cellphone and keep far from the Internet. 3:You can forget your work, your study or your family, and just enjoy the leisure time. From the moment when you start your journey, all the trifles should be locked at your house. 4:During the travel, you can kill your time slowly to have a good rest, and you can contact with different people. 6:Meet various people, experience things, which make your world bigger. 7:You just clean up your entire mind and you can get the true meaning of travel. 計算含有travel單詞的行數,不區分大小寫 [root@test3 ~]# grep -nic "travel" Travel.doc 4
2利用[]搜索集合字符
[]表示其中的某一個字符,例如[ade]表示a或d或e
找出ting hing ning
[root@test3 ~]# grep -ni "[thn]ing" Travel.doc
6:Meet various people, experience things, which make your world bigger.
7:You just clean up your entire mind and you can get the true meaning of travel.
用^符號做[]內的前綴,表示除[]內的字符之外的字符。
比如搜索oo前沒有g的字符串所在的行.使用'[^g]oo'作搜索字符串
[root@test3 ~]# grep -ni "[^g]oo" Travel.doc
8:foo
[]內可以用范圍表示,比如[a-z]表示小寫字母,[0-9]表示0~9的數字,[A-Z]則是大寫字母們。[a-zA-Z0-9]表示所有數字與英文字符。當然也可以配合^來排除字符。
[root@test3 ~]# grep -ni "[1-9]" Travel.doc
9:2020 12 31
3,行首與行尾字符^$
^表示行的開頭,$表示行的結尾(不是字符,是位置)那麼‘^$'就表示空行,因為只有
行首和行尾。
這裡^與[]裡面使用的^意義不同。它表示^後面的串是在行的開頭。
比如搜索Travel在開頭的行
[root@test3 ~]# grep -ni "^Travel" Travel.doc
1:Travel is a good way to refresh and broaden our horizon.
4,搜索以小寫字母開頭的行
[root@test3 ~]# grep -n "^[a-z]" Travel.doc
8:foot
5,搜索開頭不是英文字母的行
[root@test3 ~]# grep -n "^[^a-zA-Z]" Travel.doc
9:2020 12 31
6,$表示它前面的串是在行的結尾,
比如'\.'表示.在一行的結尾
搜索末尾是.的行
[root@test3 ~]# grep -n "\.$" Travel.doc 1:Travel is a good way to refresh and broaden our horizon. 2:During your travel, you can turn off your cellphone and keep far from the Internet. 3:You can forget your work, your study or your family, and just enjoy the leisure time. 4:From the moment when you start your journey, all the trifles should be locked at your house. 5:During the travel, you can kill your time slowly to have a good rest, and you can contact with different people. 6:They may be a window for you to know a different world. 7:Meet various people, experience things, which make your world bigger. 8:You just clean up your entire mind and you can get the true meaning of travel.
7,任意一個字符.與重復字符*
在bash中*代表通配符,用來代表任意個字符,但是在正則表達式中,他含義不同,*表示有0個或多個某個字符。
例如oo*,表示第一個o一定存在,第二個o可以有一個或多個,也可以沒有,因此代表至少一個o.
點.代表一個任意字符,必須存在。
g??d可以用'g..d'表示。good,gxxd,gabd.....都符合。
a,搜索兩個o以上的字符串
[root@test3 ~]# cat a.sh good foot vnhsdooos [root@test3 ~]# grep -n "ooo*" a.sh 1:good 2:foot 3:vnhsdooos
b,搜索g開頭和結尾的字符串在的行.*表示0個或多個任意字符
[root@test3 ~]# cat b.sh "Open Source" is a good mechanism to develop programs. The gd software is a library for drafting programs. google is the best tools for search keyword. goooooogle yes! go! go! Let's go. [root@test3 ~]# grep -n 'g.*g' b.sh 1:"Open Source" is a good mechanism to develop programs. 2:The gd software is a library for drafting programs. 3:google is the best tools for search keyword. 4:goooooogle yes! 5:go! go! Let's go.
8,限定連續重復字符的范圍{}
.*只能限制0個或多個,如果要確切的限制字符重復數量,就用{范圍}。范圍是數字用,隔開2,5表示2~5個,
2表示2個,2,表示2到更多個
注意,由於{}在SHELL中有特殊意義,因此作為正則表達式用的時候要用\轉義一下。
搜索包含兩個o的字符串的行。
woody@xiaoc:~/tmp$grep-n'o\{2\}'regular_express.txt
1:"OpenSource"isagoodmechanismtodevelopprograms.
2:appleismyfavoritefood.
3:Footballgameisnotusefeetonly.
9:Oh!thesouptastegood!
18:googleisthebesttoolsforsearchkeyword.
19:goooooogleyes!
URL:http://www.bianceng.cn/OS/Linux/201410/45685.htm
搜索g後面跟2~5個o,後面再跟一個g的字符串的行。
woody@xiaoc:~/tmp$grep-n'go\{2,5\}g'regular_express.txt
18:googleisthebesttoolsforsearchkeyword.
搜索包含g後面跟2個以上o,後面再跟g的行。。
woody@xiaoc:~/tmp$grep-n'go\{2,\}g'regular_express.txt
18:googleisthebesttoolsforsearchkeyword.
19:goooooogleyes!
注意,相讓[]中的^-不表現特殊意義,可以放在[]裡面內容的後面。
'[^a-z\.!^-]'表示沒有小寫字母,沒有.沒有!,沒有空格,沒有-的串,注意[]裡面有個小空格。
這裡列出幾個擴展特殊符號:
+,於.*作用類似,表示一個或多個重復字符。
?,於.*作用類似,表示0個或一個字符。
|,表示或關系,比如'gd|good|dog'表示有gd,good或dog的串
(),將部分內容合成一個單元組。比如要搜索glad或good可以這樣'g(la|oo)d'
()的好處是可以對小組使用+?*等。
比如要搜索A和C開頭結尾,中間有至少一個(xyz)的串,可以這樣:'A(xyz)+C'
二,awk
1、awk'/101/'file顯示文件file中包含101的匹配行。
[root@test3 ~]# awk '/192.168.46.1/' /usr/local/apache2/logs/access_log
192.168.46.1 - - [11/Sep/2013:22:59:16 -0700] "GET / HTTP/1.1" 401 381
192.168.46.1 - chen [11/Sep/2013:22:59:22 -0700] "GET / HTTP/1.1" 200 55085
192.168.46.1 - chen [11/Sep/2013:22:59:38 -0700] "GET / HTTP/1.1" 200 55085
awk'/101/,/105/'file
awk'$1==5'file
[root@test3 ~]# awk '$1=="192.168.46.1" ' /usr/local/apache2/logs/access_log
192.168.46.1 - - [11/Sep/2013:22:59:16 -0700] "GET / HTTP/1.1" 401 381
192.168.46.1 - chen [11/Sep/2013:22:59:22 -0700] "GET / HTTP/1.1" 200 55085
192.168.46.1 - chen [11/Sep/2013:22:59:38 -0700] "GET / HTTP/1.1" 200 55085
awk'$1=="CT"'file注意必須帶雙引號
awk'$1*$2>100'file
awk'$2>5&&$2<=15'file
2、awk'{printNR,NF,$1,$NF,}'file
顯示文件file的當前記錄號、域數和每一行的第一個和最後一個域。
awk'/101/{print$1,$2+10}'file顯示文件file的匹配行的第一、二個域加10。
awk'/101/{print$1$2}'file顯示文件file的匹配行的第一、二個域,但顯示時域中間沒有分隔符。
變量名 含義
ARGC 命令行變元個數
ARGV 命令行變元數組
FILENAME 當前輸入文件名
FNR 當前文件中的記錄號
FS 輸入域分隔符,默認為一個空格
RS 輸入記錄分隔符
NF 當前記錄裡域個數
NR 到目前為止記錄數
OFS 輸出域分隔符
ORS 輸出記錄分隔符
3、df|awk'$4>1000000'通過管道符獲得輸入,如:顯示第4個域滿足條件的行。
4、按照新的分隔符“|”進行操作。
awk-F"|"'{print$1}'file
awk'BEGIN{FS="[:\t|]"}
{print$1,$2,$3}'file通過設置輸入分隔符(FS="[:\t|]")修改輸入分隔符。
Sep="|"
awk-F$Sep'{print$1}'file按照環境變量Sep的值做為分隔符。
awk-F'[:\t|]''{print$1}'file按照正則表達式的值做為分隔符,這裡代表空格、:、TAB、|同時做為分隔符。
awk-F'[][]''{print$1}'file按照正則表達式的值做為分隔符,這裡代表[、]
5、awk-fawkfilefile通過文件awkfile的內容依次進行控制。
catawkfile
/101/{print"\047Hello!\047"}--遇到匹配行以後打印'Hello!'.\047代表單引號。
{print$1,$2}--因為沒有模式控制,打印每一行的前兩個域。
6、awk'$1~/101/{print$1}'file顯示文件中第一個域匹配101的行(記錄)。
[root@test3 ~]# awk '$1 ~ /127.0.0.1/{print $1}' /usr/local/apache2/logs/access_log
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.1
127.0.0.1
7、awk'BEGIN{OFS="%"}
{print$1,$2}'file通過設置輸出分隔符(OFS="%")修改輸出格式。
8、awk'BEGIN{max=100;print"max="max}BEGIN表示在處理任意行之前進行的操作。
{max=($1>max?$1:max);print$1,"Nowmaxis"max}'file取得文件第一個域的最大值。
(表達式1?表達式2:表達式3相當於:
if(表達式1)
表達式2
else
表達式3
awk'{print($1>4?"high"$1:"low"$1)}'file
9、awk'$1*$2>100{print$1}'file顯示文件中第一個域匹配101的行(記錄)。
10、awk'{$1=='Chi'{$3='China';print}'file找到匹配行後先將第3個域替換後再顯示該行(記錄)。
awk'{$7%=3;print$7}'file將第7域被3除,並將余數賦給第7域再打印。
11、awk'/tom/{wage=$2+$3;printfwage}'file找到匹配行後為變量wage賦值並打印該變量。
12、awk'/tom/{count++;}
END{print"tomwasfound"count"times"}'fileEND表示在所有輸入行處理完後進行處理。
13、awk'gsub(/\$/,"");gsub(/,/,"");cost+=$4;
END{print"Thetotalis$"cost>"filename"}'filegsub函數用空串替換$和,再將結果輸出到filename中。
123$1,200.00
123$2,300.00
123$4,000.00
URL:http://www.bianceng.cn/OS/Linux/201410/45685.htm
awk'{gsub(/\$/,"");gsub(/,/,"");
if($4>1000&&$4<2000)c1+=$4;
elseif($4>2000&&$4<3000)c2+=$4;
elseif($4>3000&&$4<4000)c3+=$4;
elsec4+=$4;}
END{printf"c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"'file
通過if和elseif完成條件語句
awk'{gsub(/\$/,"");gsub(/,/,"");
if($4>3000&&$4<4000)exit;
elsec4+=$4;}
END{printf"c1=[%d];c2=[%d];c3=[%d];c4=[%d]\n",c1,c2,c3,c4}"'file
通過exit在某條件時退出,但是仍執行END操作。
awk'{gsub(/\$/,"");gsub(/,/,"");
if($4>3000)next;
elsec4+=$4;}
END{printf"c4=[%d]\n",c4}"'file
通過next在某條件時跳過該行,對下一行執行操作。
14、awk'{printFILENAME,$0}'file1file2file3>fileall把file1、file2、file3的文件內容全部寫到fileall中,格式為
打印文件並前置文件名。
15、awk'$1!=previous{close(previous);previous=$1}
{printsubstr($0,index($0,"")+1)>$1}'fileall把合並後的文件重新分拆為3個文件。並與原文件一致。
16、awk'BEGIN{"date"|getlined;printd}'通過管道把date的執行結果送給getline,並賦給變量d,然後打印。
17、awk'BEGIN{system("echo\"Inputyourname:\\c\"");getlined;print"\nYournameis",d,"\b!\n"}'
通過getline命令交互輸入name,並顯示出來。
awk'BEGIN{FS=":";while(getline<"/etc/passwd">0){if($1~"050[0-9]_")print$1}}'
打印/etc/passwd文件中用戶名包含050x_的用戶名。
18、awk'{i=1;while(i<NF){printNF,$i;i++}}'file通過while語句實現循環。
awk'{for(i=1;i<NF;i++){printNF,$i}}'file通過for語句實現循環。
typefile|awk-F"/"'
{for(i=1;i<NF;i++)
{if(i==NF-1){printf"%s",$i}
else{printf"%s/",$i}}}'顯示一個文件的全路徑。
用for和if顯示日期
awk'BEGIN{
for(j=1;j<=12;j++)
{flag=0;
printf"\n%d月份\n",j;
for(i=1;i<=31;i++)
{
if(j==2&&i>28)flag=1;
if((j==4||j==6||j==9||j==11)&&i>30)flag=1;
if(flag==0){printf"%02d%02d",j,i}
}
}
}'
19、在awk中調用系統變量必須用單引號,如果是雙引號,則表示字符串
Flag=abcd
awk'{print'$Flag'}'結果為abcd
awk'{print"$Flag"}'結果為$Flag
三,find
查當前目錄下的所有普通文件
--------------------------------------------------------------------------------
#find.-typef-execls-l{}\;
-rw-r–r–1rootroot349282003-02-25./conf/httpd.conf
-rw-r–r–1rootroot129592003-02-25./conf/magic
-rw-r–r–1rootroot1802003-02-25./conf.d/README
查當前目錄下的所有普通文件,並在-exec選項中使用ls-l命令將它們列出
=================================================
在/logs目錄中查找更改時間在5日以前的文件並刪除它們:
$findlogs-typef-mtime+5-exec-okrm{}\;
=================================================
查詢當天修改過的文件
[root@bookclass]#find./-mtime-1-typef-execls-l{}\;
=================================================
查詢文件並詢問是否要顯示
[root@bookclass]#find./-mtime-1-typef-okls-l{}\;
<ls…./classDB.inc.php>?y
-rw-r–r–1cnscncnscn137091月1212:22./classDB.inc.php
[root@bookclass]#find./-mtime-1-typef-okls-l{}\;
<ls…./classDB.inc.php>?n
[root@bookclass]#
=================================================
查詢並交給awk去處理
[root@bookclass]#who|awk’{print$1"\t"$2}’
cnscnpts/0
=================================================
awk—grep—sed
[root@bookclass]#df-k|awk‘{print$1}’|grep-v’none’|seds"/\/dev\///g"
文件系統
sda2
sda1
[root@bookclass]#df-k|awk‘{print$1}’|grep-v’none’
文件系統
/dev/sda2
/dev/sda1
1)在/tmp中查找所有的*.h,並在這些文件中查找“SYSCALL_VECTOR",最後打印出所有包含"SYSCALL_VECTOR"的文件名
A)find/tmp-name"*.h"|xargs-n50grepSYSCALL_VECTOR
B)grepSYSCALL_VECTOR/tmp/*.h|cut-d’:'-f1|uniq>filename
C)find/tmp-name"*.h"-execgrep"SYSCALL_VECTOR"{}\;-print
2)find/-namefilename-execrm-rf{}\;
find/-namefilename-okrm-rf{}\;
3)比如要查找磁盤中大於3M的文件:
find.-size+3000k-execls-ld{};
4)將find出來的東西拷到另一個地方
find*.c-execcp‘{}’/tmp‘;’
如果有特殊文件,可以用cpio,也可以用這樣的語法:
finddir-namefilename-print|cpio-pdvnewdir
6)查找2004-11-3016:36:37時更改過的文件
#A=`find./-name"*php"`|ls-l–full-time$A2>/dev/null|grep"2004-11-3016:36:37"
四,sed
sed[options][functions]選項[options]:
-n:使用安靜(silent)模式,不在屏幕上顯示出來
-e:允許多個sed處理語句,直接大指令列模式上進行sed動作
-f:你可以將sed的動作寫在一個檔案內,-ffilename則可以執行裡面的sed動作
-r:讓sed的動作支持的是延伸型正則表達式的語法-i:直接修改讀取的檔案內容,而不是由屏幕輸出
動作說明:[n1[,n2]]fuctionn1,n2:代表選擇進行動作的行數,如10,20[動作行為]行為[functions]:
a:新增,a的後面可以接字符串,字符串會在目前行的下一行顯示
d:刪除,因為是刪除,所以d後面通常不接任何數據^O^
c:取代,c的後面可以接字符串,這些字符串可以取代n1,n2之間的行
i:插入,i的後面可以接字符串,而這些字符串會目前行的上一行顯示
p:打印,讓特定的數據顯示,通常p會與參數sed-n一起使用
s:取代,可以直接進行取代工作,如1,20s/old/new/g
范例一:使用行為a(新增)
URL:http://www.bianceng.cn/OS/Linux/201410/45685.htm
[root@www~]nl/etc/passwd|sed'2a在第2行後面添加數據'1root:x:0:0:root:/root:/bin/bash2daemon:x:1:1:daemon:/usr/sbin:/bin/sh在第2行後面添加數據
范例二:使用行為d(刪除)[root@www~]nl/etc/passwd|sed'2,5d'
范例三:使用行為c(取代行)[root@www~]nl/etc/passwd|sed'2,5c在2-5行之間的數據被我取代了'1root:x:0:0:root:/root:/bin/bash在2-5行之間的數據被我取代了6games:x:5:60:games:/usr/games:/bin/sh
范例四:僅列出/etc/passwd文件內的第5-7行[root@www~]nl/etc/passwd|sed-n'5,7p'5sync:x:4:65534:sync:/bin:/bin/sync6games:x:5:60:games:/usr/games:/bin/sh7man:x:6:12:man:/var/cache/man:/bin/sh
范例五:使用sed和ifconfig只輸出ip地址5.1.首先使用ifconfigeth0[接口名]查看詳細信息[root@www~]ifconfig
eth0eth0Linkencap:以太網硬件地址00:23:ae:68:84:e4inet地址:192.168.10.123廣播:192.168.10.255掩碼:255.255.255.0inet6地址:fe80::223:aeff:fe68:84e4/64Scope:LinkUPBROADCASTRUNNINGMULTICASTMTU:1500躍點數:1接收數據包:26597錯誤:0丟棄:0過載:0幀數:0發送數據包:17358錯誤:0丟棄:0過載:0載波:0碰撞:0發送隊列長度:1000接收字節:25801312(25.8MB)發送字節:2114879(2.1MB)中斷:165.2.使用grep進行過濾顯示[root@www~]ifconfigeth0|grep'inet'inet地址:192.168.10.123廣播:192.168.10.255掩碼:255.255.255.05.3.使用sed正則表達式去前面部分(^.*地址:)
[root@www~]ifconfigeth0|grep'inet'|sed's/^.*地址://g'192.168.10.123廣播:192.168.10.255掩碼:255.255.255.05.4.使用sed正則表達式去後面部分(廣播.*$)
[root@www~]ifconfigeth0|grep'inet'|sed's/^.*地址://g'|sed's/廣播.*$//g'192.168.10.1235.5.使用-e選項[root@www~]ifconfigeth0|grep'inet'|sed-e's/^.*地址://g'-e's/廣播.*$//g'192.168.10.1235.6.使用-f選項(把參數寫到sedfile文件中)
[root@www~]ifconfigeth0|grep'inet'|sed-fsedfile192.168.10.123
范例六:/etc/manpath.config只要MAN存在的行,但是含有#在內的批注行和空白行不要
[root@www~]cat/etc/manpath.config|grepMAN|sed's/^#.*//g'|sed'/^$/d'
MANDATORY_MANPATH/usr/manMANDATORY_MANPATH/usr/share/manMANDATORY_MANPATH/usr/local/share/manMANPATH_MAP/bin/usr/share/manMANPATH_MAP/usr/bin/usr/share/manMANPATH_MAP/sbin/usr/share/manMANPATH_MAP/usr/sbin/usr/share/manMANPATH_MAP/usr/local/bin/usr/local/manMANPATH_MAP/usr/local/bin/usr/local/share/manMANPATH_MAP/usr/local/sbin/usr/local/manMANPATH_MAP/usr/local/sbin/usr/local/share/manMANPATH_MAP/usr/X11R6/bin/usr/X11R6/manMANPATH_MAP/usr/bin/X11/usr/X11R6/manMANPATH_MAP/usr/games/usr/share/manMANPATH_MAP/opt/bin/opt/manMANPATH_MAP/opt/sbin/opt/manMANDB_MAP/usr/man/var/cache/man/fsstndMANDB_MAP/usr/share/man/var/cache/manMANDB_MAP/usr/local/man/var/cache/man/oldlocalMANDB_MAP/usr/local/share/man/var/cache/man/localMANDB_MAP/usr/X11R6/man/var/cache/man/X11R6MANDB_MAP/opt/man/var/cache/man/opt
范例七:利用sed將sedtext內的每一結尾為.的換成!sedtext的文件內容如下:
"OpenSource"isagoodmechanismtodevelopprograms.appleismyfavoritefood.Footballgameisnotusefeetonly.thisdressdoesn'tfitme.However,thisdressisabout$3183dollars.GNUisfreeairnotfreebeer.Herhairisverybeauty.Ican'tfinishthetest.Oh!Thesouptastegood.motorcycleischeapthancar.Thiswindowisclear.thesymbol'*'isrepresentedasstart.Oh!Mygod!Thegdsoftwareisalibraryfordraftingprograms.Youarethebestismeanyouaretheno.1.Theworld<Happy>isthesamewith"glad".Ilikedog.googleisthebesttoolsforsearchkeyword.goooooogleyes!go!go!Let'sgo.
[root@www~]catsedtext|sed's/\.$/\!/g'"OpenSource"isagoodmechanismtodevelopprograms!appleismyfavoritefood!Footballgameisnotusefeetonly!thisdressdoesn'tfitme!However,thisdressisabout$3183dollars!GNUisfreeairnotfreebeer!Herhairisverybeauty!Ican'tfinishthetest!Oh!Thesouptastegood!motorcycleischeapthancar!Thiswindowisclear!thesymbol'*'isrepresentedasstart!Oh!Mygod!Thegdsoftwareisalibraryfordraftingprograms!Youarethebestismeanyouaretheno.1!Theworld<Happy>isthesamewith"glad"!Ilikedog!googleisthebesttoolsforsearchkeyword!goooooogleyes!go!go!Let'sgo!
五,sort
sort命令是幫我們依據不同的數據類型進行排序,其語法及常用參數格式:
sort [-bcfMnrtk][源文件][-o 輸出文件]
補充說明:sort可針對文本文件的內容,以行為單位來排序。
參 數:
-b 忽略每行前面開始出的空格字符。
-c 檢查文件是否已經按照順序排序。
-f 排序時,忽略大小寫字母。
-M 將前面3個字母依照月份的縮寫進行排序。
-n 依照數值的大小排序。
-o<輸出文件> 將排序後的結果存入指定的文件。
-r 以相反的順序來排序。
-t<分隔字符> 指定排序時所用的欄位分隔字符。
-k 選擇以哪個區間進行排序。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
下面通過幾個例子來講述Sort的使用。
(1)sort將文件的每一行作為一個單位,相互比較,比較原則是從首字符向後,依次按ASCII碼值進行比較,最後將他們按升序輸出。
[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
用戶可以保存排序後的文件內容,或把排序後的文件內容輸出至打印機。下例中用戶把排序後的文件內容保存到名為result的文件中。
$ Sort seq.txt > result
(2)sort的-u選項
它的作用很簡單,就是在輸出行中去除重復行。
[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
pear
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
pear
[rocrocket@rocrocket programming]$ sort -u seq.txt
apple
banana
orange
pear
URL:http://www.bianceng.cn/OS/Linux/201410/45685.htm
pear由於重復被-u選項無情的刪除了。
(3)sort的-r選項
sort默認的排序方式是升序,如果想改成降序,就加個-r就搞定了。
[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort number.txt
1
2
3
4
5
[rocrocket@rocrocket programming]$ sort -r number.txt
5
4
3
2
1
(5)sort的-o選項
由於sort默認是把結果輸出到標准輸出,所以需要用重定向才能將結果寫入文件,形如sort filename > newfile。
但是,如果你想把排序結果輸出到原文件中,用重定向可就不行了。
[rocrocket@rocrocket programming]$ sort -r number.txt > number.txt
[rocrocket@rocrocket programming]$ cat number.txt
[rocrocket@rocrocket programming]$
看,竟然將number清空了。
就在這個時候,-o選項出現了,它成功的解決了這個問題,讓你放心的將結果寫入原文件。這或許也是-o比重定向的唯一優勢所在。
[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort -r number.txt -o number.txt
[rocrocket@rocrocket programming]$ cat number.txt
5
4
3
2
1
(6) sort的-n選項
你有沒有遇到過10比2小的情況。我反正遇到過。出現這種情況是由於排序程序將這些數字按字符來排序了,排序程序會先比較1和2,顯然1小,所以就將10放在2前面喽。這也是sort的一貫作風。
我們如果想改變這種現狀,就要使用-n選項,來告訴sort,“要以數值來排序”!
[rocrocket@rocrocket programming]$ cat number.txt
1
10
19
11
2
5
[rocrocket@rocrocket programming]$ sort number.txt
1
10
11
19
2
5
[rocrocket@rocrocket programming]$ sort -n number.txt
1
2
5
10
11
19
(7) sort的-t選項和-k選項
如果有一個文件的內容是這樣:
[rocrocket@rocrocket programming]$ cat facebook.txt
banana:30:5.5
apple:10:2.5
pear:90:2.3
orange:20:3.4
這個文件有三列,列與列之間用冒號隔開了,第一列表示水果類型,第二列表示水果數量,第三列表示水果價格。那麼我想以水果數量來排序,也就是以第二列來排序,如何利用sort實現?幸好,sort提供了-t選項,後面可以設定間隔符。指定了間隔符之後,就可以用-k來指定列數了。
[rocrocket@rocrocket programming]$ sort -n -k 2 -t ‘:’ facebook.txt
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3
六,uniq
– c 顯示輸出中,在每行行首加上本行在文件中出現的次數。它可取代- u和- d選項。
– d 只顯示重復行。
– u 只顯示文件中不重復的各行。
– n 前n個字段與每個字段前的空白一起被忽略。一個字段是一個非空格、非制表符的字符串,彼此由制表符和空格隔開(字段從0開始編號)。
+n 前n個字符被忽略,之前的字符被跳過(字符從0開始編號)。
– f n 與- n相同,這裡n是字段數。
– s n 與+n相同,這裡n是字符數。
接下來通過實踐實例說明:
===========================================
[root@stu100 ~]# cat test
boy took bat home
boy took bat home
girl took bat home
boy took bat home
boy took bat home
dog brought hat home
dog brought hat home
dog brought hat home
看test文件的內容
============================================
[root@stu100 ~]# uniq test
boy took bat home
girl took bat home
boy took bat home
dog brought hat home
uniq命令不加任何參數,僅顯示連續重復的行一次
============================================
[root@stu100 ~]# uniq -c test
2 boy took bat home
1 girl took bat home
2 boy took bat home
3 dog brought hat home
1
-c 參數顯示文件中每行連續出現的次數。
============================================
[root@stu100 ~]# cat test |sort | uniq -c
1
4 boy took bat home
3 dog brought hat home
1 girl took bat home
排序後再顯示
============================================
[root@stu100 ~]# uniq -d test
boy took bat home
boy took bat home
dog brought hat home
-d選項僅顯示文件中連續重復出現的行。
============================================
[root@stu100 ~]# uniq -u test
girl took bat home
-u選項顯示文件中沒有連續出現的行。
============================================
[root@stu100 ~]# uniq -f 2 -s 2 test
boy took bat home
忽略每行的前2個字段,忽略第二 個空白字符和第三個字段的首字符,結果at home
============================================
[root@stu100 ~]# uniq -f 1 test
boy took bat home
dog brought hat home
忽 略每行的第一個字段,這樣boy ,girl開頭的行看起來是連續重復的行。
============================================
[root@stu100 ~]# uniq -D test
boy took bat home
boy took bat home
boy took bat home
boy took bat home
dog brought hat home
dog brought hat home
dog brought hat home
顯示所有重復的行,每個重復的行都顯示
七,cut
一、定義
正如其名,cut的工作就是“剪”,具體的說就是在文件中負責剪切數據用的。cut是以每一行為一個處理對象的,這種機制和sed是一樣的。
2、剪切依據
cut命令主要是接受三個定位方法:
第一,字節(bytes),用選項-b
第二,字符(characters),用選項-c
第三,域(fields),用選項-f
例:
一,按字節cut:
注意:一個空格算一個字節,一個漢字算三個字節
[root@localhost ~]# date
2011年08月11日 星期四20:44:52 EDT
[root@localhost ~]# date |cut -b 1-4 取前四個字節
2011
[root@localhost ~]# date |cut -b 1-6
2011
[root@localhost ~]# date |cut -b 1-7 一個漢字算三個字節
2011年
[root@localhost ~]# date |cut -b 1-10
2011年08
多個定位之間用逗號隔開:
[root@localhost ~]# date |cut -b 1-7,10
2011年8
[root@localhost ~]# date |cut -b 10,1-7 cut會先把-b後面所有的定位進行從小到大排序,然後再提取
URL:http://www.bianceng.cn/OS/Linux/201410/45685.htm
2011年8
負號的使用:
[root@localhost ~]# date |cut -b -4
2011
[root@localhost ~]# date |cut -b 4-
1年08月11日 星期四21:05:30 EDT
[root@localhost ~]# date |cut -b -4,4-
2011年08月11日 星期四21:06:53 EDT
-4表示從第一個字節到第四個字節,而4-表示從第四個字節到行尾。這兩種情況下,都包括了第4個字節“1”。如果我執行date |cut -b -4,4-,會輸出整行,不會出現連續兩個重疊的1
二,按字符cut:
按字符cut相對比較簡單,中文字符和空格都算一個字符。
[root@localhost ~]# date |cut -c 1-5
2011年
[root@localhost ~]# date |cut -c 5,9,13
年月日
三、按域cut
以/etc/passwd文件為例:
[root@localhost ~]# head -n5 /etc/passwd |cut -d : -f 1,3-5
root:0:0:root
bin:1:1:bin
daemon:2:2:daemon
adm:3:4:adm
lp:4:7:lp
-d指定域分隔符,-f 指定要剪出哪幾個域,這個與awk的輸出特定字段功能一樣。
-d選項的默認間隔符就是制表符,所以當你就是要使用制表符的時候,完全就可以省略-d選項,而直接用-f來取域就可以了
如何分的清空格和制表符?
[root@localhost ~]# cat test 這個文件各單詞間存在單個空格、制表符和多個空格
data11【單個空格 】data12 【制表符】data13
data21【多個空格】data22【單個空格】data23
data31 【單個空格 】data32 【 多個空格data33
[root@localhost ~]# sed -n l test 用sed命令可以讓制表符原形畢露~
data11 data12\tdata13$
data21 data22 data23$
data31 data32 data33$
[root@localhost ~]# cat test |cut -f 2
data13
data21 data22 data23
data31 data32 data33
[root@localhost ~]# cat test |cut -d " " -f 2 cut的間隔符只允許是一個字符
cut: the delimiter must be a single character
請嘗試執行“cut --help”來獲取更多信息。
[root@localhost ~]# cat test |cut -d " " -f 2
data12 data13 中間那個空白字符是制表符
第一個空格後面還是空格,所以輸出空格
data32 單個空格後面就是data32