Shell從入門到精通教學(xué)課件:第9章 基本文本處理_第1頁
Shell從入門到精通教學(xué)課件:第9章 基本文本處理_第2頁
Shell從入門到精通教學(xué)課件:第9章 基本文本處理_第3頁
Shell從入門到精通教學(xué)課件:第9章 基本文本處理_第4頁
Shell從入門到精通教學(xué)課件:第9章 基本文本處理_第5頁
已閱讀5頁,還剩121頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

第9章基本文本處理本章主要涉及到的知識點(diǎn)有:使用echo命令輸出文本:主要介紹echo命令的基本語法,顯示普通字符串、轉(zhuǎn)義字符、變量、命令執(zhí)行結(jié)果等各種數(shù)據(jù)的方法。文本的格式化輸出:主要介紹對文本格式化輸出的各種方法,包括制表符、fold、fmt以及pr等命令的使用方法。使用sort命令對文本排序:主要介紹sort命令的基本語法,以及如何根據(jù)不同的標(biāo)準(zhǔn)對文本進(jìn)行排序。文本的統(tǒng)計(jì):主要介紹如何創(chuàng)建行號,統(tǒng)計(jì)行數(shù)、單詞數(shù)以及字符數(shù)等。使用cut命令選取特定的文本:主要介紹cut命令的基本語法,以及如何根據(jù)不同的要求來對文本列進(jìn)行選擇。使用paste命令拼接文本行:主要介紹paste命令的基本語法以及如何根據(jù)用戶需求來并行拼接多個(gè)文件的列。使用join命令聯(lián)接文本行:主要介紹joint命令的基本語法以及使用不同的方法來聯(lián)接2個(gè)文本文件。使用tr命令替換文件內(nèi)容:主要介紹tr命令的基本語法,如何去除重復(fù)出現(xiàn)的字符、刪除空行、大小寫轉(zhuǎn)換以及刪除指定字符等。9.1使用echo命令輸出文本在進(jìn)行Shell程序設(shè)計(jì)的過程中,文本的輸出非常重要。例如程序?yàn)橛脩籼峁┑奶崾拘畔⒁约俺绦虻膱?zhí)行結(jié)果等,這些信息都是作為文本輸出的。本節(jié)將介紹最簡單的文本輸出命令echo。9.1.1顯示普通字符串在本書前面幾章的例子中,我們已經(jīng)接觸過echo命令了。echo命令的功能就是輸出一行文本。在Shell程序中,多用于顯示提示信息或者程序產(chǎn)生的數(shù)據(jù)。echo命令的基本語法如下:echo[options]string…在上面的語法中,options表示命令選項(xiàng)。echo命令常用選項(xiàng)比較少,只有一個(gè)-n,該選項(xiàng)表示不輸出行尾的換行符。在默認(rèn)情況下,每執(zhí)行一次echo命令,都會在輸出信息的行尾加上一個(gè)換行符。參數(shù)string表示要輸出的文本,用戶可以同時(shí)指定多個(gè)文本,這些文本之間用空格隔開?!纠?-1】演示如何使用echo命令輸出用戶提示信息echo-n"Whatisyourfirstname?"readfirstecho-n"Whatisyourlastname?"readlastecho-n"Whatisyourmiddlename?"readmiddleecho-n"Whatisyourbirthday?"readbirthday[root@linuxchapter9]#./ex9-1.shWhatisyourfirstname?ChunxiaoWhatisyourlastname?ZhangWhatisyourmiddlename?Whatisyourbirthday?1973-07-199.1.2顯示轉(zhuǎn)義字符除了支持普通文本的輸出之外,echo命令還支持簡單的轉(zhuǎn)義字符的輸出。通過轉(zhuǎn)義字符,echo命令可以控制輸出的格式,或者是輸出某些特殊的字符,例如退格符、換頁符以及制表符等。下表列出了echo命令支持的轉(zhuǎn)義字符。如果要使得echo命令支持轉(zhuǎn)義字符,還必須使用-e選項(xiàng)?!纠?-2】演示各種轉(zhuǎn)義字符的使用方法#!/bin/bash#退格符echo-e"thisisa\bstring."#禁止繼續(xù)輸出后面的文本echo-e"hello\cworld."#換行符echo-e"hello\nworld."#使用制表符輸出表格echo-e"Alice\t99"echo-e"John\t82"echo-e"Tom\t91"[root@linuxchapter9]#./ex9-2.sh01 thisisstring.02 hellohello03 world.04 Alice 9905 John 8206 Tom919.1.3顯示變量用戶可以使用echo語句將程序中的變量的值打印出來,在前面的許多例子中,都使用echo語句來輸出某些信息?!纠?-3】演示使用echo語句顯示變量的方法#!/bin/bashecho-n"Pleaseinputaname:"readname#輸出變量的值echo"Hello,$name"v1="sing"v2="danc"#錯(cuò)誤的輸出變量值的方法echo"Weare$v1ing,weare$v2ing."[root@linuxchapter9]#./ex9-3.shPleaseinputaname:ChunxiaoHello,ChunxiaoWeare,weare.【例9-4】使用花括號界定變量名#!/bin/bashecho-n"Pleaseinputaname:"readnameecho"Hello,$name"v1="sing"v2="danc"echo"Weare${v1}ing,weare${v2}ing."[root@linuxchapter9]#./ex9-4.shPleaseinputaname:ChunxiaoHello,ChunxiaoWearesinging,wearedancing.9.1.4換行和不換行默認(rèn)情況下,echo命令在輸出文本的末尾會自動追加一個(gè)換行符。【例9-5】演示echo命令會自動追加換行符#!/bin/bashecho"Youarealwaysincontrolofyoursearchsettings."echo"Here'saquickreviewoftheoptionsthatyoucanset."[root@linuxchapter9]#./ex9-5.shYouarealwaysincontrolofyoursearchsettings.Here'saquickreviewoftheoptionsthatyoucanset.【例9-6】演示使用-n選項(xiàng)來使得多條echo語句輸出到同一行中#!/bin/bash#使用-n選項(xiàng)輸出文本echo-n"Youarealwaysincontrolofyoursearchsettings."echo"Here'saquickreviewoftheoptionsthatyoucanset."[root@linuxchapter9]#./ex9-6.shYouarealwaysincontrolofyoursearchsettings.Here'saquickreviewoftheoptionsthatyoucanset.【例9-7】演示如何使用\c來避免換行#!/bin/bash#使用轉(zhuǎn)義字符避免換行echo-e"Youarealwaysincontrolofyoursearchsettings.\c"echo"Here'saquickreviewoftheoptionsthatyoucanset."[root@linuxchapter9]#./ex9-7.shYouarealwaysincontrolofyoursearchsettings.Here'saquickreviewoftheoptionsthatyoucanset.9.1.5顯示命令執(zhí)行結(jié)果除了顯示文本之外,echo命令還可以將Shell命令執(zhí)行結(jié)果顯示出來。不過,在顯示命令執(zhí)行結(jié)果的時(shí)候,需要使用反引號將命令引用起來,其語法如下:echo`command`【例9-8】演示如何使用echo命令顯示命令的執(zhí)行結(jié)果#!/bin/bash#顯示date命令的執(zhí)行結(jié)果echo`date`#顯示ls命令的執(zhí)行結(jié)果echo`ls`[root@linuxchapter9]#./ex9-8.shFriFeb2223:31:58HKT2013ex9-1.shex9-2.shex9-3.shex9-5.shex9-6.shex9-7.shex9-8.sh9.1.6echo命令執(zhí)行結(jié)果的重定向重定向的操作符為>或者>>,在目標(biāo)文件已經(jīng)存在的情況下,前者會覆蓋目標(biāo)文件原有的內(nèi)容,而后者則會將數(shù)據(jù)追加到原來文件的末尾。將echo命令的執(zhí)行結(jié)果重定向的語法比較簡單,直接將重定向操作符放在echo語句的結(jié)尾,然后再指定一個(gè)文件名即可?!纠?-9】演示將echo命令執(zhí)行結(jié)果重定向的方法#!/bin/bash#將要輸出的信息寫入文件echo"Hello,world.">hello.txt#將輸出的信息追加到文件的結(jié)尾echo"Hello,Chunxiao.">>hello.txt[root@linuxchapter9]#./ex9-9.sh[root@linuxchapter9]#morehello.txtHello,world.Hello,Chunxiao.9.2文本的格式化輸出盡管echo命令語句提供了最基本的輸出功能,但是在某些場合,用戶可能需要對文本的輸出格式進(jìn)行更加細(xì)致地控制。在Shell程序中,文本的格式化輸出主要有制表符、pr命令以及fmt命令等。本節(jié)將介紹這幾個(gè)命令的使用方法。9.2.1使用Unix制表符在Shell中,制表符通常使用轉(zhuǎn)義字符\t表示,其中字母t表示Tab,即表格的英文單詞Table的前3個(gè)字母。前面已經(jīng)講過,echo命令支持制表符的輸出。但是為了使用轉(zhuǎn)義字符,需要使用-n選項(xiàng)?!纠?-10】演示使用echo命令結(jié)合制表符來輸出九九乘法表#!/bin/bash#雙層嵌套循環(huán)輸出乘法表for((i=1;i<10;i++))dofor((j=1;j<=$i;j++))do#使用制表符對齊列

echo-n-e"$i*$j\t"done#換行

echo""done[root@linuxchapter9]#./ex9-10.sh1*12*12*23*13*23*34*14*24*34*45*15*25*35*45*56*16*26*36*46*56*67*17*27*37*47*57*67*78*18*28*38*48*58*68*78*89*19*29*39*49*59*69*79*89*99.2.2使用fold命令格式化行顧名思義,fold命令的功能是將超過指定寬度的文本行進(jìn)行折疊處理,使得超過指定寬度的字符轉(zhuǎn)到下一行輸出。fold命令的基本語法如下:fold[options][file…]在上面的語法中,options表示選項(xiàng),fold命令常用的選項(xiàng)有:-b:按字節(jié)計(jì)算寬度。默認(rèn)情況下,fold命令按列來計(jì)算寬度。-s:在空格處折斷行。-w:指定寬度,默認(rèn)值是80列。file參數(shù)用來指定要輸出的文件名,可以是多個(gè)文件,文件名之間用空格隔開。【例9-11】演示使用fold命令格式化輸出文本的方法[root@linuxchapter9]#catdemo1.txtYouarealwaysincontrolofyoursearchsettings.Here'saquickreviewoftheoptionsthatyoucanset(andchangewheneveryoulike)onthesearchsettingspage.Youcanreachthatpagebyclickingthegeariconinthetoprightcornerofthesearchresultspage,thenclickingSearchsettings.Youcanalsovisitthepagedirectlyat/preferences.Theoptionsaregroupedintothreecategories:Searchresults,Languages,andLocation.Clickthethreelinksontheleftsideofthepagetochangecategories.然后使用fold命令來格式化輸出該文件的內(nèi)容,命令如下:[root@linuxchapter9]#fold-w90demo1.txt【例9-11】通過-s選項(xiàng)使得文本行在換行時(shí)保留單詞的完整,同樣指定文本行的寬度為90列[root@linuxchapter9]#fold-s-w90demo1.txt【例9-12】通過重定向?qū)old命令的輸出結(jié)果保存到文件[root@linuxchapter9]#fold-w90demo1.txt>formtedtext.txt[root@linuxchapter9]#catformtedtext.txt9.2.3使用fmt命令格式化段落與fold命令相比,fmt命令提供了更多的功能。fmt命令是Shell中的一個(gè)簡單的文本格式化工具,其名稱來自于格式化(format)的縮寫。fmt命令的基本語法如下:fmt[-width][option]...[file]...其中,-width選項(xiàng)用來指定文本行的列數(shù),默認(rèn)為75列,即每行顯示75個(gè)字符。option表示各種命令選項(xiàng),常用的選項(xiàng)有:-c:保留每個(gè)段落的前2行的縮進(jìn),該段落剩余的行的左邊距與第2行相同。-t:該選的功能與-c選項(xiàng)基本相同,但是在使用-t選項(xiàng)時(shí),每個(gè)段落的第1行和第2行的縮進(jìn)必須是不相同的,否則第1行將被看作是一個(gè)單獨(dú)的段落。-s:只折斷超出指定寬度的行,不合并少于指定寬度的行。-u:統(tǒng)一空格的個(gè)數(shù),單詞之間保留1個(gè)空格,句子之間保留2個(gè)空格。-w:指定每個(gè)行的最大寬度,默認(rèn)值為75列。file參數(shù)為要格式化其內(nèi)容的文件名,可以同時(shí)指定多個(gè)文件,文件名之間用空格隔開。如果指定文件名為-,則fmt命令會從標(biāo)準(zhǔn)輸入,即鍵盤讀取文本。【例9-13】演示使用-w選項(xiàng)來指定行的最大長度為80列#!/bin/bash#指定行長度str=`fmt-c-w80demo2.txt`echo"$str"【例9-14】本例對【例9-13】進(jìn)行改進(jìn),加上-s選項(xiàng),以避免合并行#!/bin/bash#不合并不足指定行寬的行str=`fmt-s-c-w80demo2.txt`echo"$str"9.2.4使用rev命令反轉(zhuǎn)字符順序rev命令的功能是用來反轉(zhuǎn)文件中的文本行的字符順序,其名稱來自于反轉(zhuǎn)(reverse)的前3個(gè)字母。rev命令的基本語法如下:rev[file...]其中,file表示要處理的文件的文件名列表,如果是多個(gè)文件,則文件名之間用空格隔開。#!/bin/bash#反轉(zhuǎn)文本行str=`revdemo3.txt`echo"$str"[root@linuxchapter9]#./ex9-15.sh987654321.dlrow,olleH【例9-15】演示rev命令的使用方法9.2.5使用pr命令格式化文本頁pr命令是一個(gè)非常有用的工具,其功能主要是將文本文件的內(nèi)容轉(zhuǎn)換成適合打印的格式。pr命令的名稱來自于打?。╬rint)的前2個(gè)字母,其基本語法如下:pr[option]...[file]...#!/bin/bash#格式化文本頁str=`pr-4demo4.txt`echo"$str"【例9-16】演示使用pr命令將該文件的內(nèi)容進(jìn)行格式化處理#!/bin/bash#自定義頁眉str=`pr-h"ListofCountries"-a-f-4demo4.txt`echo"$str"【例9-17】演示如何自定義頁眉,文本水平分欄以及使用換頁符來代替換行符9.3使用sort命令對文本排序在Linux或者UNIX中,許多數(shù)據(jù)都是以文本文件的形式存在。因此,用戶經(jīng)常需要對這些文本進(jìn)行排序,為此,UNIX提供了sort命令來完成這個(gè)任務(wù)。本節(jié)將介紹sort命令的使用方法。9.3.1sort命令的基本用法Shell中的sort命令有3種執(zhí)行模式,分別為排序文本、檢查文件是否已經(jīng)排序以及合并文件。在本節(jié)當(dāng)中,對這3種執(zhí)行模式將依次詳細(xì)介紹。在本小節(jié)中,首先介紹最基本的排序功能。sort命令的基本語法如下:sort[option]...[file]...#!/bin/bash#使用默認(rèn)選項(xiàng)對文件排序result=`sortdemo5.txt`#將輸出結(jié)果保存到文件echo"$result">sorted_default.txt#顯示排序結(jié)果catsorted_default.txt【例9-18】演示使用最簡單的sort命令對demo5.txt文件進(jìn)行排序[root@linuxchapter9]#./ex9-18.shA_Few_Good_Men KL 445 5851Alien HK 119 1982Aliens HK 532 4892Boys_in_Company_C HK 192 2192Star_Wars HK 301 4102The_Hill KL 63 2972Toy_Story HK 239 39729.3.2使用單個(gè)關(guān)鍵字排序用戶可以使用-k選項(xiàng)來定義排序關(guān)鍵字,其基本語法如下:-kpos1[,pos2]其中,pos1表示排序關(guān)鍵字的起始位置,pos2表示排序關(guān)鍵字的結(jié)束位置,這兩者之間用逗號隔開。通常情況下,組成排序關(guān)鍵字都是以列為單位的。此時(shí),post1和pos2就是關(guān)鍵字的起始列和結(jié)束列的列號。列號從1開始,即第1列為1,第2列為2,依此類推。#!/bin/bash#通過第2列和第3列排序result=`sort-k2,3demo5.txt`echo"$result"[root@linuxchapter9]#./ex9-19.shAlien HK 119 1982Boys_in_Company_C HK 192 2192Toy_Story HK 239 3972Star_Wars HK 301 4102Aliens HK 532 4892A_Few_Good_Men KL 445 5851The_Hill KL 63 2972【例9-19】演示使用2個(gè)列作為一個(gè)關(guān)鍵字來進(jìn)行排序的方法#!/bin/bashif[$1-gt4]thenecho"columnno.couldnotbegreaterthan4."exitfi#僅指定起始列result=`sort-r-k$1demo6.txt`echo"$result"[root@linuxchapter9]#./ex9-20.sh2Alien HK 119 1982Boys_in_Company_CHK 239 2192Toy_Story HK 239 3972Star_Wars HK 301 4102Aliens HK 532 4892A_Few_Good_MenKL 445 5851The_Hill KL 63 2972【例9-20】演示只指定sort命令排序關(guān)鍵字的起始列的情況#!/bin/bash#根據(jù)第4列的第14~15個(gè)字符排序,并輸出到文件sort-t''-n-k4.14,4.15demo7.txt>sorted_logcatsorted_log[root@linuxchapter9]#./ex9-21.sh

18--[25/Feb/2013:01:27:14+0800]"GET/HTTP/1.1"2002853718--[25/Feb/2013:01:27:23+0800]"GET/HTTP/1.1"2002853726--[24/Feb/2013:05:28:55+0800]"\x80}\x01\x03\x01"302-26--[24/Feb/2013:05:28:55+0800]"\x80}\x01\x03\x01"302-5--[24/Feb/2013:06:40:28+0800]"\x16\x03\x01"302-18--[25/Feb/2013:07:40:40+0800]"GET/HTTP/1.1"2002853818--[25/Feb/2013:07:40:52+0800]"GET/HTTP/1.1"200285378--[24/Feb/2013:10:10:16+0800]"\x80w\x01\x03\x01"302-18--[24/Feb/2013:10:45:27+0800]"GET/HTTP/1.1"2002853818--[24/Feb/2013:10:45:27+0800]"GET/HTTP/1.1"20028538…【例9-21】演示使用某個(gè)列的子串作為關(guān)鍵字的組成部分的方法9.3.3根據(jù)指定的列排序一般情況下,sort命令都是使用幾個(gè)列組成一個(gè)關(guān)鍵字來排序的。如果用戶只想根據(jù)某一個(gè)列排序的話,同樣也可以通過-k選項(xiàng)來實(shí)現(xiàn)。實(shí)際上這是一種特殊的情況,即起始列的列號和終止列的列號相同。因此,根據(jù)某個(gè)指定的列排序的語法如下:-kpos,pos其中,pos表示要排序的列的列號。同樣,列號也是從1開始編號。如果只想根據(jù)某個(gè)列中的子串來排序,可以指定起始字符和終止字符,語法如下:-kpos.[start],pos[.end]#!/bin/bashif[$1-gt4]thenecho"columnno.couldnotbegreaterthan4."exitfi#根據(jù)指定的列排序result=`sort-k$1,$1demo6.txt`echo"$result"[root@linuxchapter9]#./ex9-22.sh1A_Few_Good_Men KL 445 5851Alien HK 119 1982Aliens HK 532 4892Boys_in_Company_C HK 239 2192Star_Wars HK 301 4102The_Hill KL 63 2972Toy_Story HK 239 3972【例9-22】演示根據(jù)用戶輸入的列號來對文件進(jìn)行排序的方法9.3.4根據(jù)關(guān)鍵字降序排序sort命令還提供了-r選項(xiàng)和r修飾符,用來實(shí)現(xiàn)根據(jù)關(guān)鍵字降序排列。其中-r選項(xiàng)是作為全局選項(xiàng)使用,其作用對象為sort命令中所有沒有附件修飾符的列。修飾符r可以附加在組成關(guān)鍵字的列號后面,其作用域?yàn)樗郊拥牧小?!/bin/bash

#使用-r選項(xiàng)降序排序result=`sort-r-k2,3demo5.txt`

echo"$result"[root@linuxchapter9]#./ex9-23.shThe_Hill KL 63 2972A_Few_Good_Men KL 445 5851Aliens HK 532 4892Star_Wars HK 301 4102Toy_Story HK 239 3972Boys_in_Company_C HK 192 2192Alien HK 119 1982【例9-23】演示根據(jù)用戶輸入的列號來對文件進(jìn)行排序的方法#!/bin/bash#使用修飾符實(shí)現(xiàn)降序result=`sort-k2,3rdemo5.txt`echo"$result"[root@linuxchapter9]#./ex9-24.shThe_Hill KL 63 2972A_Few_Good_MenKL 445 5851Aliens HK 532 4892Star_Wars HK 301 4102Toy_Story HK 239 3972Boys_in_Company_CHK 192 2192Alien HK 119 1982【例9-24】演示了如何使用修飾符實(shí)現(xiàn)【例9-21】的降序操作9.3.5數(shù)值列的排序默認(rèn)情況下,sort命令會將所有的列看作是字符串,并且按照字符串的排序規(guī)則進(jìn)行排序。為了使得sort命令能夠正確處理數(shù)值字段,用戶需要使用-n選項(xiàng)或者修飾符n。#!/bin/bash#對第3列按數(shù)值排序result=`sort-n-k3,3demo5.txt`echo"$result"[root@linuxchapter9]#./ex9-25.shThe_Hill KL 63 2972Alien HK 119 1982Boys_in_Company_CHK 192 2192Toy_Story HK 239 3972Star_Wars HK 301 4102A_Few_Good_MenKL 445 5851Aliens HK 532 4892【例9-25】使用-n選項(xiàng)對demo5.txt的第3列進(jìn)行排序9.3.6自定義列分隔符默認(rèn)情況下,sort命令會將連續(xù)的空格或者制表符作為列的分隔符。但是,在實(shí)踐當(dāng)中,并不總是這樣,可能會存在著其他的分隔符,例如冒號、逗號或者分號。用戶完全有可能使用這些符號來分隔各個(gè)列。#!/bin/bash#自定義分隔符result=`sort-t:-k3n,3/etc/passwd`echo"$result"[root@linuxchapter9]#./ex9-26.shroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologin…【例9-26】演示自定義列分隔符的方法9.3.7刪除重復(fù)的行在處理文本數(shù)據(jù)時(shí),去掉重復(fù)的行通常是一件非常棘手的事情,尤其是在數(shù)據(jù)量比較大的情況下。但是,sort命令提供了一個(gè)-u選項(xiàng),可以很方便地完成這個(gè)任務(wù)。[root@linuxchapter9]#catdemo5.txtToy_Story HK 239 3972The_Hill KL 63 2972Star_Wars HK 301 4102Boys_in_Company_C HK 192 2192Aliens HK 532 4892Alien HK 119 1982A_Few_Good_Men KL 445 5851Boys_in_Company_C HK 192 2192[root@linuxchapter9]#sortdemo5.txtA_Few_Good_Men KL 445 5851Alien HK 119 1982Aliens HK 532 4892Boys_in_Company_C HK 192 2192Boys_in_Company_C HK 192 2192Star_Wars HK 301 4102The_Hill KL 63 2972Toy_Story HK 239 3972[root@linuxchapter9]#sort-udemo5.txtA_Few_Good_Men KL 445 5851Alien HK 119 1982Aliens HK 532 4892Boys_in_Company_C HK 192 2192Star_Wars HK 301 4102The_Hill KL 63 2972Toy_Story HK 239 39729.3.8根據(jù)多個(gè)關(guān)鍵字排序用戶可以在sort命令中同時(shí)指定多個(gè)關(guān)鍵字,sort命令會依次根據(jù)各個(gè)關(guān)鍵字來排序。也即是說,如果同時(shí)指定了3個(gè)關(guān)鍵字,則sort命令會首先根據(jù)第1個(gè)關(guān)鍵字排序,如果遇到第1個(gè)關(guān)鍵字相同的情況,則會根據(jù)第2個(gè)關(guān)鍵字排序。同理,如果前面2個(gè)關(guān)鍵字都相同的情況下,再根據(jù)第3個(gè)關(guān)鍵字排序,依此類推。如果用戶指定的關(guān)鍵字的值全部相同的情況下,sort命令會對整個(gè)文本行根據(jù)當(dāng)前系統(tǒng)語言環(huán)境的排序規(guī)則進(jìn)行排序。使用多個(gè)關(guān)鍵字排序的語法如下:sort[option]-kpos1,pos2-kpos3,pos4,...[file…]也就是說,用戶可以同時(shí)使用多個(gè)-k選項(xiàng)來定義多個(gè)排序關(guān)鍵字,這些關(guān)鍵字會依次作用于要排序的文本。#!/bin/bash#根據(jù)第3列的數(shù)值降序,第4列的數(shù)值升序排序result=`sort-k3,3nr-k4,4ndemo6.txt`echo"$result"[root@linuxchapter9]#catdemo6.txtToy_Story HK 239 3972The_Hill KL 63 2972Star_Wars HK 301 4102Boys_in_Company_CHK 239 2192Aliens HK 532 4892Alien HK 119 1982A_Few_Good_MenKL 445 5851[root@linuxchapter9]#./ex9-27.shAliens HK 532 4892A_Few_Good_MenKL 445 5851Star_Wars HK 301 4102Boys_in_Company_CHK 239 2192Toy_Story HK 239 3972Alien HK 119 1982The_Hill KL 63 2972【例9-27】演示根據(jù)多個(gè)關(guān)鍵字排序的方法9.3.9使用sort命令合并文件使用sort命令可以很方便地合并多個(gè)文件,同時(shí)將文本文件的內(nèi)容進(jìn)行排序。當(dāng)使用sort命令合并文件時(shí),其基本語法如下:sortfile1file2…其中file1、file2等表示要合并的文件的文件名,這些文件名之間用空格隔開。sort命令會根據(jù)指定的順序依次將各個(gè)文件的內(nèi)容合并。#!/bin/bash#合并文件并輸出磁盤文件result=`sortdemo5.txtdemo6.txt>result.txt`catresult.txt[root@linuxchapter9]#./ex9-28.shA_Few_Good_MenKL 445 5851A_Few_Good_MenKL 445 5851Alien HK 119 1982Alien HK 119 1982Aliens HK 532 4892Aliens HK 532 4892Boys_in_Company_CHK 192 2192Boys_in_Company_CHK 239 2192Star_Wars HK 301 4102Star_Wars HK 301 4102The_Hill KL 63 2972The_Hill KL 63 2972Toy_Story HK 239 3972Toy_Story HK 239 3972【例9-28】演示了使用默認(rèn)選項(xiàng)合并2個(gè)文件9.4文本的統(tǒng)計(jì)在Shell編程中,文本的統(tǒng)計(jì)也非常重要。為了統(tǒng)計(jì)文本,Shell提供了許多有用的工具來完成文本的統(tǒng)計(jì),例如wc、cat以及grep等。本節(jié)將介紹如何使用這些工具實(shí)現(xiàn)文本的統(tǒng)計(jì)。9.4.1輸出含有行號的文本行在Shell中,有許多命令都可以輸出行號,其中包括cat、grep以及wc等。下面分別介紹如何使用這些命令輸出行號。[root@linuxchapter9]#cat-nex9-1.sh1#!/bin/bash23echo-n"Whatisyourfirstname?"4readfirst5echo-n"Whatisyourlastname?"6readlast7echo-n"Whatisyourmiddlename?"8readmiddle9echo-n"Whatisyourbirthday?"10readbirthdaycat命令提供了一個(gè)-n選項(xiàng),通過該選項(xiàng),cat命令會在每一個(gè)文本行的前面添加一個(gè)行號,如下所示:[root@linuxchapter9]#grep-n""ex9-1.sh1:#!/bin/bash2:3:echo-n"Whatisyourfirstname?"4:readfirst5:echo-n"Whatisyourlastname?"6:readlast7:echo-n"Whatisyourmiddlename?"8:readmiddle9:echo-n"Whatisyourbirthday?"10:readbirthday與cat命令一樣,grep命令也有一個(gè)名稱為-n的選項(xiàng),該選項(xiàng)使得grep命令在輸出結(jié)果的時(shí)候會顯示符合指定篩選條件的文本行的行號。為了能夠輸出所有的文本行,用戶可以使用空串作為grep命令的參數(shù),如下所示:除了前面介紹的幾個(gè)命令之外,Shell還提供了一個(gè)名稱為nl的命令用來為文本添加行號,其基本語法如下:nl[option]...[file]...nl命令的常用選項(xiàng)有:-b:顯示風(fēng)格,可以取a、t以及n等值,a表示為所有行添加行號,t表示僅僅為非空行添加行號,n表示不添加行號。-i:行號的增量,默認(rèn)值為1。-v:行號的起始值,默認(rèn)值為1。參數(shù)file表示要添加行號的文件的列表。#!/bin/bash#為文本添加行號,并輸出到文件nl-baex9-1.sh>textwithlineno.txtcattextwithlineno.txt[root@linuxchapter9]#./ex9-29.sh1#!/bin/bash23echo-n"Whatisyourfirstname?"4readfirst5echo-n"Whatisyourlastname?"6readlast7echo-n"Whatisyourmiddlename?"8readmiddle9echo-n"Whatisyourbirthday?"10readbirthday【例9-29】演示使用nl命令為文本添加行號的方法9.4.2統(tǒng)計(jì)行數(shù)在Shell程序中,用戶可以使用grep以及wc等命令來統(tǒng)計(jì)文本行的數(shù)量。下面分別介紹這2種統(tǒng)計(jì)文本行數(shù)的方法。grep命令提供了一個(gè)名稱為-c的選項(xiàng)用來統(tǒng)計(jì)符合篩選條件的文本行的行數(shù),下面的例子就演示了這個(gè)選項(xiàng)的使用方法。#!/bin/bashecho-n"Pleaseinputaname:"#讀取用戶輸入數(shù)據(jù)readnamewhile[$name!="e"]do#統(tǒng)計(jì)含有用戶輸入數(shù)據(jù)的行數(shù)

quantity=`grep-c"$name"demo5.txt`echo"$quantityrecordscontains$name."echo-n"Pleaseinputaname:"readnamedone[root@linuxchapter9]#./ex9-30.shPleaseinputaname:a2recordscontainsa.Pleaseinputaname:A3recordscontainsA.Pleaseinputaname:C1recordscontainsC.Pleaseinputaname:e[root@linuxchapter9]#【例9-30】演示使用grep命令統(tǒng)計(jì)記錄數(shù)wc命令是Shell中用來對文本進(jìn)行各種統(tǒng)計(jì)的命令,其基本語法如下:wc[option]...[file]...其中,wc命令常用的選項(xiàng)有: -c:統(tǒng)計(jì)文本的字節(jié)數(shù)。 -m:統(tǒng)計(jì)字符數(shù)。 -l:統(tǒng)計(jì)行數(shù)。 -L:統(tǒng)計(jì)最長行的長度。 -w:統(tǒng)計(jì)單詞數(shù)。與其他的命令一樣,wc命令可以接受多個(gè)文件名作為參數(shù),這些文件名之間用空格隔開。#!/bin/bash#統(tǒng)計(jì)文本行數(shù)lines=`catex9-1.sh|wc-l`echo"thefilehas$lineslines."[root@linuxchapter9]#./ex9-31.shthefilehas10lines.【例9-31】演示通過-l選項(xiàng)來統(tǒng)計(jì)文本文件的行數(shù)#!/bin/bash#統(tǒng)計(jì)/etc目錄下面有多少個(gè)以conf為擴(kuò)展名的文件count=`find/etc-name"*.conf"|wc-l`echo"$countfileshavebeenfound."[root@linuxchapter9]#./ex9-32.sh411fileshavebeenfound.【例9-32】使用find結(jié)合wc命令來統(tǒng)計(jì)/etc目錄下面以.conf為擴(kuò)展名的文件的數(shù)量9.4.3統(tǒng)計(jì)單詞數(shù)和字符數(shù)在許多語言中,例如英語,單詞之間都是通過空格來隔開的。在wc命令中,也是通過空格來區(qū)分單詞的。用戶可以通過-w選項(xiàng)來統(tǒng)計(jì)文本中的單詞的數(shù)量。另外,通過-m選項(xiàng)可以統(tǒng)計(jì)文本的字符數(shù)。#!/bin/bash#統(tǒng)計(jì)單詞數(shù),只取得數(shù)量words=`catdemo1.txt|wc-w`echo"thereare$wordswordsinfiledemo1.txt"#統(tǒng)計(jì)字符數(shù)chars=`catdemo1.txt|wc-m`echo"thereare$charscharactersinfiledemo1.txt"[root@linuxchapter9]#./ex9-33.shthereare89wordsinfiledemo1.txtthereare528charactersinfiledemo1.txt【例9-33】使用cat命令配合wc命令來取得文件中的單詞的數(shù)量和字符數(shù)量9.5使用cut命令選取文本列對于關(guān)系型數(shù)據(jù)庫而言,用戶可以在水平方向上選擇行,也可以在垂直方向上選擇列。與此相對應(yīng),針對文本文件,Shell也提供了相應(yīng)的操作方法。前面介紹的排序和篩選都是以行為單位進(jìn)行的,操作的結(jié)果也都是行。而cut命令則是從垂直方向上對文本進(jìn)行操作。本節(jié)將介紹如何使用cut命令操作文本列。9.5.1cut命令及其語法

cut命令的基本語法如下:cutoption...[file]...在上面的語法中,option表示選項(xiàng),cut命令常用的選項(xiàng)有:-b:只選擇指定的字節(jié)。-c:只選擇指定的字符。-d:自定義列分隔符,默認(rèn)值為制表符。-f:只選擇列表中指定的文本列,文本列用列號表示,多個(gè)列之間用逗號隔開。-n:取消分割多字節(jié)字符。-s:不輸出不包含列分隔符的行。file參數(shù)表示要處理得文件的列表,多個(gè)文件名之間用空格分隔。9.5.2選擇指定的文本列

選取指定的文本列需要使用cut命令的-f選項(xiàng),該選項(xiàng)接收一個(gè)文本列的列表,cut命令會從文本文件中選擇列表中列出的列。#!/bin/bash#自定義分隔符為冒號,選擇第1列和第6列result=`cut-d":"-f1,6passwd`echo"$result"[root@linuxchapter9]#./ex9-34.shroot:/rootbin:/bindaemon:/sbinadm:/var/adm…【例9-34】演示如何通過cut命令從passwd文件中選擇某些列9.5.3選擇指定數(shù)量的字符除了從文本中選擇列之外,用戶還可以通過cut命令從每一行中選擇指定數(shù)量的字符。在選擇字符時(shí),cut命令的語法如下:cut-clist其中,-c選項(xiàng)表示選擇字符(character)。list參數(shù)表示要選擇的范圍,可以是以下語法形式:1-4,63,5,8-4,83-#!/bin/bash#選擇指定的列result=`cut-c1-3,5passwd`echo"$result"[root@linuxchapter9]#./ex9-35.shroo:binxdaeoadmxlp::syn:shud…【例9-35】演示通過cut命令從文本文件中選擇指定列的方法9.5.4排除不包含列分隔符的行在某些情況下,用戶的數(shù)據(jù)文件可能會存在著錯(cuò)誤的數(shù)據(jù)行。這些錯(cuò)誤的數(shù)據(jù)行在格式上與正確的數(shù)據(jù)行存在著區(qū)別,例如不包含正確的列分隔符。cut命令的-s選項(xiàng)可以幫助用戶排除掉這些不包含正確列分隔符的行。#!/bin/bash#提取所有行的第1列cut-d":"-f1passwd>allusers.txtecho"allusers:"#顯示所有的行catallusers.txt#只提取正確的行cut-s-d":"-f1passwd>validusers.txtecho"validusers:"#顯示所有正確的行catvalidusers.txt[root@linuxchapter9]#./ex9-36.shallusers:rootbin…uservalidusers:rootbin…openvpn_as【例9-36】演示通過cut命令從文本文件中選擇指定列的方法9.6使用paste命令拼接文本列在上一節(jié)中,我們介紹了cut命令,這個(gè)命令非常強(qiáng)大,可以從文本中選擇某些列。有了這個(gè)命令之后,用戶可能會反過來考慮,如果能夠?qū)⒍鄠€(gè)文件的列合并起來,那豈不更好?Linux中的paste命令就是實(shí)現(xiàn)這個(gè)功能的,本節(jié)將介紹如何使用paste命令來處理文本文件。9.6.1paste命令及其語法前面介紹的cut命令可以將文本文件縱向分割,使得原來文件的某些列重新生成一個(gè)新的文件。paste命令的功能恰好與cut命令相反。該命令的主要功能是將某些文件的文本行并行地聯(lián)接在一起,形成一個(gè)新的文件。新文件的列數(shù)等于參與組合的所有文件的列的總和,新文件的行數(shù)與參與組合的文件的行數(shù)相等。paste命令的基本語法如下:paste[option]...[file]..其中,paste命令常用的選項(xiàng)有: -d:指定拼接結(jié)果中列分隔符。默認(rèn)情況下paste命令生成的文件使用制表符分隔列。 -s:將多個(gè)文件串行地拼接在一起,即將后面文件的內(nèi)容追加到前面一個(gè)文件的后面。其中,-s選項(xiàng)表示將各個(gè)文件依次連接在一起。也就是說,將后面一個(gè)文件的文本行追加在前面一個(gè)文件的內(nèi)容的后面。因此,如果使用-s選項(xiàng),則生成的文件的列數(shù)與參與組合的文件的列數(shù)相同,但是行數(shù)等于參與組合的所有文件的行數(shù)之和。file參數(shù)表示參與拼接的文件列表,文件名之間用空格隔開。如果省略文件名,則表示從標(biāo)準(zhǔn)輸入接收文本數(shù)據(jù)。#!/bin/bash#拼接2個(gè)文件,并輸出到磁盤文件pastestudents.txtphones.txt>contactinfo.txt#顯示拼接結(jié)果catcontactinfo.txt[root@linuxchapter9]#./ex9-37.sh200200110 Abdul 200200110 13611499594200200164 Abram 200200164 13682239867200200167 Bartley 200200167 13710153203200200168 Bennett 200200168 13622259071200200172 Cecil 200200172 13430324699200200173 John 200200179 13640656767200200187 Cat【例9-37】通過paste命令和重定向?qū)tudents.txt和phones.txt這2個(gè)文件拼接起來9.6.2自定義列分隔符默認(rèn)情況下,paste命令會使用制表符作為新生成的文件的列分隔符。但是,用戶可以使用-d選項(xiàng)來自定義所需要的分隔符,例如逗號或者分號等。#!/bin/bash#自定義列分隔符paste-d","students.txtphones.txt>contactinfo.txtcatcontactinfo.txt[root@linuxchapter9]#./ex9-38.sh200200110Abdul,200200110 13611499594200200164Abram,200200164 13682239867200200167Bartley,200200167 13710153203200200168Bennett,200200168 13622259071200200172Cecil,200200172 13430324699200200173John,200200179 13640656767200200187Cat,【例9-38】使用逗號作為paste命令拼接結(jié)果的列分隔符9.6.3拼接指定的文本列paste命令并不直接支持只選擇文件中的某些列來拼接。但是,用戶可以通過間接的途徑來使得最后生成的文件中僅僅含有指定的列。在這里介紹兩種方法,第一種就是先使用cut命令將需要的列從各個(gè)文件中提取出來,然后再使用paste命令進(jìn)行拼接;第二種的順序恰好相反,先使用paste命令進(jìn)行拼接各個(gè)文件,然后再使用cut命令從生成的文件中提取所需要的列。由于第一種方法的執(zhí)行效率相對較高,所以建議使用第一種方法來拼接指定的文本列。#!/bin/bash

#選擇students.txt文件的第1列cut-f1students.txt>students.tmp#選擇phones.txt文件的第2列cut-f2phones.txt>phones.tmp#將生成的2個(gè)臨時(shí)文件拼接pastestudents.tmpphones.tmp>contactinfo.txt#輸出拼接結(jié)果catcontactinfo.txt[root@linuxchapter9]#./ex9-39.sh200200110 13611499594200200164 13682239867200200167 13710153203200200168 13622259071200200172 13430324699200200173 13640656767200200187【例9-39】通過cut命令和重定向?qū)tudents.txt的第1列和phones.txt的第2列拼接起來,并且去掉其他的列#!/bin/bash#先將2個(gè)文件拼接pastestudents.txtphones.txt>contactinfo.tmp#再從拼接結(jié)果中選擇第1和3列cut-f1,3contactinfo.tmp>contactinfo.txt#輸出拼接結(jié)果catcontactinfo.txt[root@linuxchapter9]#./ex9-39.sh200200110 13611499594200200164 13682239867200200167 13710153203200200168 13622259071200200172 13430324699200200173 13640656767200200187【例9-40】先通過paste命令聯(lián)接2個(gè)文件,然后再通過cut命令提取指定數(shù)據(jù)列9.7使用join命令聯(lián)接文本列在9.6一節(jié)中,我們介紹了paste命令,使用該命令,可以將多個(gè)文件的文本行進(jìn)行拼接。同時(shí),也提出了一個(gè)問題,那就是paste命令只能根據(jù)文本行的順序進(jìn)行拼接,而不能基于某個(gè)關(guān)鍵字進(jìn)行聯(lián)接。在Shell中,用戶可以使用join命令來解決這個(gè)問題。本節(jié)將介紹join命令的使用方法。9.7.1join命令及其語法join命令是一個(gè)非常有趣的Shell命令。對于熟悉關(guān)系型數(shù)據(jù)庫的用戶來說,一定會了解其中的數(shù)據(jù)表的聯(lián)接的概念。所謂聯(lián)接,就是根據(jù)用戶指定的條件,將多個(gè)數(shù)據(jù)表的中的數(shù)據(jù)行聯(lián)接起來,形成一個(gè)新的表,這個(gè)表的列由參與聯(lián)接的多個(gè)表的列構(gòu)成。join命令就是用來聯(lián)接這些文本文件中的數(shù)據(jù)行的,它是根據(jù)參與聯(lián)接的兩個(gè)文本文件的公共列來聯(lián)接數(shù)據(jù)行。其基本語法如下:join[option]...file1file2#!/bin/bash#使用默認(rèn)選項(xiàng)聯(lián)接2個(gè)文件result=`joinstudents.txtphones.txt>contactinfo.txt`catcontactinfo.txt[root@linuxchapter9]#./ex9-41.sh200200110 Abdul 13611499594200200164 Abram 13682239867200200167 Bartley 13710153203200200168 Bennett 13622259071200200172 Cecil 例9-41】演示最簡單的join命令的使用方法9.7.2指定聯(lián)接關(guān)鍵字列默認(rèn)情況下,join命令會將兩個(gè)文件的第1列作為關(guān)鍵字列進(jìn)行比較。因此,在例9-39中,盡管用戶并沒有明確指定關(guān)鍵字列,但是join命令仍然將students.txt和phones.txt這2個(gè)文件的第1列作為關(guān)鍵字列進(jìn)行比較。但是,在實(shí)際情況中,作為關(guān)鍵字的列并不總是第1列。用戶還可以使用-1或者-2選項(xiàng)來分別用作關(guān)鍵字的列。其中的-1代表從第1個(gè)文件中指定關(guān)鍵字列,-2代表從第2個(gè)文件中指定關(guān)鍵字列。這2個(gè)選項(xiàng)都使用列號作為參數(shù)值。#!/bin/bash#指定students.txt的第1列和scores.txt文件的第2列作為列關(guān)鍵字result=`join-11-22students.txtscores.txt>studentsscores.txt`catstudentsscores.txt[root@linuxchapter9]#./ex9-42.sh200200110 Abdul 1 78200200164 Abram 1 78200200167 Bartley 2 92200200168 Bennett 3 87200200172 Cecil 4 65【例9-42】使用-1和-2選項(xiàng)來指定關(guān)鍵字列9.7.3內(nèi)聯(lián)接文本文件所謂內(nèi)聯(lián)接文本文件,實(shí)際上就是使用默認(rèn)選項(xiàng)的join命令對2個(gè)文本文件的聯(lián)接操作。在默認(rèn)情況下,join命令只輸出關(guān)鍵字匹配的文本行,而忽略關(guān)鍵字不匹配的文本行。圖9-14描述了內(nèi)聯(lián)接的原理,在圖9-14中,左邊的圓代表第1個(gè)文件的行,右邊的圓代表第2個(gè)文件的行,中間的陰影代表內(nèi)聯(lián)接的結(jié)果,表示只有關(guān)鍵字匹配的文本行才會出現(xiàn)在結(jié)果中。9.7.4左聯(lián)接文本文件所謂左聯(lián)接,是指在聯(lián)接結(jié)果中輸出左邊文件的所有行,即使在右邊的文件中沒有匹配的行。在左聯(lián)接中,對于在右邊的文件中沒有相應(yīng)關(guān)鍵字的行,由右邊文件所形成的列使用空白符填充。圖9-15描述了左聯(lián)接文本文件的原理,在圖9-15中,左右兩個(gè)圓分別代表參與聯(lián)接的兩個(gè)文件,陰影部分代表左聯(lián)接的結(jié)果,從圖中可以看出,左邊文件的所有行都包含在輸出結(jié)果中。在join命令中,要實(shí)現(xiàn)左聯(lián)接,可以使用以下語法:join-a1filenumfile1file2其中,選項(xiàng)-a1表示顯示第1個(gè)文件的所有的行,無論是否匹配成功。#!/bin/bash#左聯(lián)接文件result=`join-a1students.txtphones.txt>contactinfo.txt`catcontactinfo.txt[root@linuxchapter9]#./ex9-43.sh200200110 Abdul 13611499594200200164 Abram 13682239867200200167 Bartley 13710153203200200168 Bennett 13622259071200200172 Cecil 13430324699200200173 John200200187 Cat【例9-43】演示通過join命令左聯(lián)接文件的方法9.7.5右聯(lián)接文本文件右聯(lián)接的原理與左聯(lián)接恰好相反,它是將右邊文件的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論