shell學習系列(三).通配符 當在使用命令行時,有很多時間都用來查找所需要的文件,shell提供了一套完整的字符串模式匹配規(guī) 則,或者稱之為元字符,這樣就可以按照所要求的模式來匹配文件.還可以使用字符類型來匹配文件名. 1.使用* 使用星號*可以匹配文件名中的任何字符串,在下面的例子中,給出文件名模式app*,它的意思是文 件名以app開頭,后面可以跟隨任何字符串,包括空字符串: *也可以用在文件名模式的開頭,如: ls *.doc 匹配所有以.doc結尾的文件名. *還可以用在文件名的當中,如: ls cl*.sed 用于匹配所有以cl開頭,后面跟任何字符串,最后以.sed結尾的文件名. 2.使用? 使用可以匹配文件名中的任何單個字符,如: ls ??R* 文件名以任意兩個字符開頭,接著是R,后面跟任何字符的文件. ls conf??.log 文件名以conf開頭,中間是任意兩個字符,最后以.log結尾的文件. ls f??*s 所有以f開頭,中間是任意兩個字符,后面跟隨任意字符串,并以s結尾的文件名. 3.使用[...]和[!...] 使用[...]可以用來匹配方括號[]中的任何字符.在這一方法中,還可以使用一個橫杠-來連接兩個 字母或數(shù)字,以此來表示一個范圍. ls [io]* 列出以i或者o開頭的文件名 ls log.[0-9]* 匹配所有以log.開頭,后面跟隨一個數(shù)字,然后可以是任意字符串的文件名. ls log.[!0-9]* 表示非數(shù)字開頭的字符串. 為了列出所有以大寫字母開頭的文件名,可以用: ls [A-Z]* 為了列出所有以小寫字母開頭的文件名,可以用: ls [a-z]* 為了列出所有以數(shù)字開頭的文件名,可以用: ls .*
| | |
=====================================================
在shell腳本中,可以用幾種不同的方式讀入數(shù)據(jù):可以使用標準輸入,缺省為鍵盤,或者指定一個文件
作為輸入.對于輸出也是一樣,如果不指定某個文件作為輸出,標準輸出問題和終端屏幕相關聯(lián),也可以
把信息指定到一個文件中.
1.echo
使用echo命令可以顯示文本行或變量,或者把字符串輸入到文件.它的一般形式為:
echo string
echo命令有很多功能,其中最常用的是下面幾個:
\c 不換行
\t 跳格
\n 換行
如果是Linux系統(tǒng),那么必須使用-n選項來禁止echo命令后換行:
必須使用-e選項才能使轉義符生效.
如果希望在echo命令輸出之后附加換行,可以使用\n選項.
如果想把一個字符串輸出到文件中,使用重定向符號>.
引號是一個特殊的字符,所以必須要使用反斜杠\來使shell忽略它的特殊意義.假設希望使用echo
命令輸出這樣的字符串: "/dev/rmt0", 那么只要在引號前面加上反斜杠就可以了:
echo "\"/dev/rmt0\""
2.read
可以使用read語句從鍵盤或文件的某一行文本中讀入信息,并將其賦給一個變量.如果只指定了一
個變量,那么read將會把所有的輸入賦給該變量,直至遇到第一個文件結束符或回車.
它的一般形式為:
read varible1 varible2
在下面的例子中,只指定了一個變量 ,它將被賦予直至回車之前的所有內容.
read name
hello i am a man
echo $name
hello i am a man
在下面的例子中,給出了兩個變量,它們分別被賦予名字和姓氏,shell將用空格作為變量之間的分
隔符.
read name surname
john doe
echo $name $surname
john doe
如果文本域過長,shell將所有的超長部分賦予最后一個變量.
3.cat
cat是一個簡單而通用的命令,可以用它來顯示文件內容,創(chuàng)建文件,還可以用它來顯示控制字符.
在使用cat命令時要注意,它不會在文件分頁符處停下來.它會一下顯示完整個文件.如果希望每次顯示
一頁,可以使用more命令或把cat命令的輸出通過管道傳遞到另外一個具有分頁功能的命令中.
cat myfile | more
cat命令的一般形式為:
cat [options] filename1 ... filename2
cat命令最有用的選項就是:
-v顯示控制字符.
如果希望顯示myfile1, myfile2, myfile3這三個文件,可以用:
cat myfile1 myfile2 myfile3
如果希望創(chuàng)建一個名為bigfile的文件,該文件包含上述三個文件的內容,可以把上面命令的輸出
重定向到新文件中:
cat myfile1 myfile2 myfile3 > bigfile
4.管道
可以通過管道把一個命令的輸出傳遞給另一個命令作為輸入,管道用豎杠|表示,它的一般形式為:
命令1|命令2
5.tee
tee命令作用可以用字母T來形象地表示,它把輸出的一個副本輸送到標準輸出,另一個副本拷貝到
相應的文件中.如果希望在看到輸出的同時,也將其存入一個文件,那么這個命令再合適不過了.
它的一般形式為:
tee -a files
其中-a表示追加到文件末尾
在執(zhí)行某些命令或腳本時,如果希望把輸出保留下來,tee命令非常方便.
who | tee who.out
就將who的結果顯示給標準輸出,同時保存到who.out文件中.
如:
who | tee who.out | awk '{print $1"\t"$2}' | tee -a who.out
6.標準輸入,輸出和錯誤
6.1標準輸入
標準輸入是文件描述符0,它是命令的輸入,缺省是鍵盤,也可以是文件或其它命令的輸出.
6.2標準輸出
標準輸出是文件描述符1,它是命令的輸出,缺省是屏幕,也可以是文件.
6.3標準錯誤
標準錯誤是文件描述符2,這是命令錯誤的輸出,缺省是屏幕,同樣也可以是文件.
7.文件重定向
在執(zhí)行命令時,可以指定命令的標準輸入,輸出和錯誤,要實現(xiàn)這一點就需要使用文件重定向,在對
標準錯誤進行重定向時,必須要使用文件描述符.但是對于標準輸入和輸出來說,這不是必需的.
command > filename 把標準輸出重定向到一個新文件中
command >> filename 把標準輸出重定向到一個新文件中(追加)
command 1> filename 把標準輸出重定向到一個文件中
command > filename 2>&1 把標準輸出和標準錯誤重定向到一個文件中
command 2>filename 把標準錯誤重定向到一個文件中
command 2>> filename 把標準錯誤重定向到一個文件中(追加)
command >> filename 2>&1 把標準輸出和標準錯誤重定向到一個文件中(追加)
command < filename > filename2以filename文件作為標準輸入,以filename2文件作為標準輸出
command < filename 以filename文件作為標準輸入
command << delimiter 從標準輸入中讀入,直到遇到delimiter分界符
command <&m 把文件描述符m作為標準輸入
command >&m 把標準輸出重定向到文件描述符m中
command <&- 關閉標準入
7.1 重定向標準輸出
在下面的命令中,把/etc/passwd文件中的用戶ID域按照用戶名排列,該命令的輸出重定向到
sort.out文件中,要提醒注意的是,在使用sort命令的時候,重定向符號一定要離開sort命令兩個空格,
否則該命令會把它當作輸入文件.
cat passwd | awk -F: '{print $1}' | sort 1>sort.out
可以把很多命令的輸出追回到同一個文件中.
ls -l | grep ^d >> file.out
如果希望把標準輸出重定向到文件中,可以用>filename.如果希望追加到已有的文件中,那么可以
使用>>filename.如果想創(chuàng)建一個長度為0的空文件,可以用>filename.
7.2 重定向標準輸入
可以指定命令的標準輸入.
sort < name.txt
在上面的命令中,sort命令的輸入是采用重定向的方式給出的.不過也可以直接把相應的文件作為
該命令的參數(shù).
sort name.txt
在發(fā)送郵件的時候,可以用重定向的方法發(fā)送一個文件中的內容,如:
mail louise < contents.txt
重定向操作符command << delimiter是一種非常有用的命令,通過都被稱為"此處"文檔.shell將
分界符delimiter之后直至下一個同樣的分界符之前的所有內容作為輸入,遇到下一個分界符,shell就
知道輸入結束了.這一命令對于自動或遠程的例程非常有用.可以用任意定義分界符delimiter,最常見
的是EOF.
7.3 重定向標準錯誤
為了重定向標準錯誤,可以指定文件描述符2.如:
grep "trident" missiles 2> /dev/null
8.結合使用標準輸出和標準錯誤
一個快速發(fā)現(xiàn)錯誤的方法就是,先將輸出重定向到一個文件中,然后再把標準錯誤重定向到另外一
個文件中.下面給出一個例子:
在審計文件時,其中一個的確存在,而且包含一些信息,而另一個由于某種原因已經(jīng)不存在了,想把
這兩個文件合并到accounts.out文件中.
cat account_qtr.doc account_end.doc 1> accounts.out 2>accoutns.err
現(xiàn)在如果出現(xiàn)了錯誤相應的錯誤將會保存在accounts.err文件中.
9.合并標準輸出和標準錯誤
在合并標準輸出和標準錯誤的時候,切記shell是從左至右分析相應的命令的.
cleanup > cleanup.out 2>&1
在上面的例子中,將cleanup腳本的輸出重定向到cleanup.out文件中,而且其錯誤也被重定向到相
同的文件中.
10.exec
exec命令可以用來替代當前shell,換句話說,并沒有啟動子shell.使用這一命令時任何現(xiàn)有的環(huán)
境將會被清除,并重新啟動一個shell,它的一般形式為:
shell command
其中的command通常是一個shell腳本.
當這個腳本結束時,相應的會話就可能結束了.exec在對文件描述符進行操作的時候,它不會覆蓋
當前的shell.
11.使用文件描述符
可以使用exec命令通過文件描述符打開和關閉文件,在下面的例子中.選用了文件描述符4,下面的
腳本只是從stock.txt文件中讀了兩行,然后把這兩行回顯出來.
該腳本的第一行把文件描述符4指定為標準輸入,然后打開stock.txt文件,接下來兩行的作用是讀
入了兩行文本,接著,作為標準輸入的文件描述符4被關閉.最后line1和line2兩個變量所含有的內容都
被回顯到屏幕上.
#!/bin/sh
exec 4<&0 0<stock.txt
read line1
read line2
exec 0<&4
echo $line1
echo $line2
=====================================================
shell學習系列(六).grep1.grep grep的一般格式為: grep [選項] 基本正則表達式 [文件] 這里基本正則表達式可為字符串 1.1 雙引號引用 在grep命令中輸入字符串參數(shù)時,最好將其用雙引號括起來,例如"mystring".這樣做有兩個原因,一是以防被誤解為shell命令,二是可以用來查找多個單詞組成的字符串,例 如"jet plane".如果不用雙引號將其括起來,那么單詞plane將被誤認為是一個文件,查詢結果將返回"文件不存在"的錯誤信息. 在調用變量時,也應該使用雙引號,諸如:grep "$MYVAR" 文件名,如果不這樣,將沒有返回結果. 在調用模式匹配時,應該使用單引號. 1.2 grep選項 常用的grep選項有: -c 只輸出匹配行的行數(shù) -i 不區(qū)分大小寫(只適用于單字符) -h 查詢多文件時不顯示文件名 -l 查詢多文件時只輸出包含匹配字符的文件名 -n 顯示匹配行及行號 -s 不顯示不存在或無匹配文件的錯誤信息 -v 顯示不包含匹配文件的所有行 1.3 查詢多個文件 如果要在當前目錄下所有.doc文件中查找字符串"sort",方法如下: grep "sort" *.doc 或在所有文件中查詢單詞"sort it" grep "sort it" * 1.4 行匹配 grep -c "48" data.f grep返回4,表示是有4行包含字符串"48" 1.5 行數(shù) 顯示滿足匹配模式的所有行行數(shù): grep -n "48" data.f 行數(shù)輸出在第一列,后跟包含48的每一匹配行. 1.6 顯示非匹配行 顯示所有不包含48的各行: grep -v "48" data.f 1.7 精確匹配 在抽取字符串"48"時,返回結果也可能會返回包含"484", "483"等含有"48"的其它字符串,實際上應精確抽取只包含48"的各行,可以采用如下方式來只提取含有48的項: grep "48\>" data.f 或者是 grep "\<48\>" data.f grep -w "48" data.f 1.8 大小寫敏感 缺省情況下,grep是大小寫敏感的,如果要查詢大小寫不敏感的字符串,必須使用-i選項. 2.grep和正則表達式 使用正則表達式使模式匹配加入一些規(guī)則,因此可以在抽取信息中加入更多選項,使用正則表達式最好用單引號括起來,這樣可以防止grep中使用的專有模式與一些shell命令的 特殊方式相混淆. 2.1 模式范圍 假定要抽取代碼為484或483的城市位置. grep '48[34]' data.f 2.2 不匹配行首 如果要抽出記錄,使其行首不是4或8,可以在方括號中使用^記號,表明查詢在行首開始. grep "^[^48]" data.f 如果要使行首不是48,則: grep -v "^48" data.f 2.3 設置大小寫 使用-i開關可以屏蔽月份Sept的大小寫敏感,也可以用另外一種方式.這里使用[]模式抽取各行包含Sept 和 sept的所有信息. grep "[Ss]ept" data.f 2.4 匹配任意字符 如果抽取以L開頭,以D結尾的所有代碼,可使用下述方法.因為已知代碼長度為5個字符: grp "k...d" data.f 2.5 日期查詢 一個常用的查詢模式是日期查詢,先查詢所有以5開始以1996或1998結尾的所有記錄.使用模式5..199[6,8].這意味著第一個字符為5,后跟兩個點, grep "5..199[6,8]" data.f 2.6 范圍組合 必須學會使用[]抽取信息,假定要取得城市代碼,第一個字符為任意字符,第二個字符在0到5之間,第三個字符在0到6之間,使用下列模式即可實現(xiàn): grep "[0-9][0-5][0-6]" data.f 2.7 模式出現(xiàn)機率 抽取包含數(shù)字4至少重復出現(xiàn)兩次的所有行,方法如下: grep '4\{2,\}' data.f 同樣,抽取記錄使之包含數(shù)字999,方法如下: grep '9\{3,\}' data.f 2.8 使用grep匹配"與"或者"或"模式 grep命令加-E參數(shù),這一擴展允許使用擴展模式匹配,例如,要抽取城市代碼為219或216,方法如下: grep -E '219|216' data.f 2.9 空行 結合使用^和$可查詢空行,使用-n參數(shù)顯示實際行數(shù). grep '^$' myfile 2.10匹配特殊字符 查詢有特殊含義的字符,諸如$ . ' " * [] ^ | \ + ?,必須在特定字符前加\,假設要查詢包含"."的所有行,腳本如下: grep '\.' myfile 或者是一個雙引號 grep '\"' myfile 以同樣的方式,如果要查詢文件名conftroll.conf,腳本如下: grep 'conftroll\.conf' myfile 2.11查詢格式化文件名 使用正則表達式可匹配任意文件名,系統(tǒng)中對文本文件有其標準的命名格式,一般最后六個小字字符,后跟句點.接著是兩個大寫字符.例如,要在一個包含各類文件名的文件 filename.deposit中定位這類文件名,方法如下: grep '^[a-z]\{1,6\}\.[A-Z]\{1,2\}' filename.deposit 2.12查詢IP地址 使用[0-9]\{3\}\.[0-9]\{3\}\. 含義是任意數(shù)字出現(xiàn)3次,后跟句點,接著是任意數(shù)字出現(xiàn)3次,后跟句點. 3.類名 grep允許使用國際字符模式匹配或匹配模式的類名形式. 類 等價的正則表達式 [[:upper:]] [A-Z] [[:lower:]] [a-z] [[:digit:]] [0-9] [[:alnum:]] [0-9a-zA-Z] [[:space:]] 空格或TAB鍵 [[:alpha:]] [a-zA-Z] 要抽取產(chǎn)品代碼,該代碼以5開頭,后跟至少兩個大寫字母,使用的腳本如下: grep '5[[:upper:]][[:upper:]]' data.f 如果要抽取以P或D結尾的所有產(chǎn)品代碼,方法如下: grep '[[:upper:]][[:upper:]][P,D]' data.f 4.系統(tǒng)grep命令 4.1 目錄 如果要查詢目錄列表中的目錄,方法如下: ls -l | grep '^d' 如果在一個目錄中查詢不包含目錄的所有文件,方法如下: ls -l | grep '^[^d]' 要查詢其它用戶和其它用戶組成員有可執(zhí)行權限的目錄集合,方法如下: ls -l | grep '^d.....x..x' 4.2 passwd文件 grep "root" /etc/passwd 上述腳本查詢/etc/passwd文件是否包含root字符串. 4.3 使用ps命令 使用帶有ps x命令的grep可查詢系統(tǒng)上運行的進程,ps x命令意為顯示系統(tǒng)上運行的所有進程列表.輸出也應包含此grep命令,因為grep命令創(chuàng)建了相應進程,ps x將找到它,在 grep命令中,使用-v選項可丟棄ps命令中的grep進程. ps ax | grep "named" | grep -v "grep" 4.4 對一個字符串使用grep grep不只應用于文件,也可應用于字符串,為此使用echo字符串命令,然后對grep命令使用管道輸入. STR="mary joe peter pauline" echo $STR| grep "mary" |
|
|