《Linux与unix Shell编程指南》 总结
《Linux與unix Shell編程指南》 總結
標簽: linux網絡dstcron服務器 2011-01-10 18:27 3742人閱讀 評論(0) 收藏 舉報 分類: Linux(21)版權聲明:本文為博主原創文章,未經博主允許不得轉載。
目錄(?)[+]
Unix命令行程序和內建指令(更多)
|
|
|
|
|
|
|
|
1. 文件權限
[plain] view plaincopyprint?文件類型 ? ??文件權限 ??文件屬主 ??文件屬主dave 的用戶組 ??文件字節長度 ? ?文件更新時間 ? ? ?文件名
?- ? ? ? ? ? ? ? ? ? ?rw-r--r--?1 ? ?dave ? ? ? ? ? ? ? ?admin ? ?? ? ? ? ? ? ? ? 300 ? ? ? ? ? ? ? ? ?Fed 19 22:05 ? ? ? ?myfile
?1 .文件類型
文件權限位前面的那個字符,我們例子中的橫杠就是文件的類型,即普通文件類型。
文件類型有七種,它可以從 ls -l命令所列出的結果的第一位看出:
d?? 目錄。l? 符號鏈接(指向另一個文件)。s? 套接字文件。b? 塊設備文件。c? 字符設備文件。p? 命名管道文件。
-? ? 普通文件,或者更準確地說,不屬于以上幾種類型的文件。
2.文件的權限:
文件的權限可分為三類:1) 文件屬主,創建該文件的用戶。如 -rw:文件屬主權限 這是前面三位
2) 同組用戶,擁有該文件的用戶組中的任何用戶。如 -r-: 同組用戶權限 這是中間三位
3) 其他用戶,即不屬于擁有該文件的用戶組的某一用戶。如 -r-:其他用戶權限 這是最后三位
3.修改權限: chmod
1)符合模式:chmod [who] ?operator [permission] ?filename
who的含義是:u文件屬主權限。g同組用戶權限。o其他用戶權限。a所有用戶(文件屬主、同組用戶及其他用戶)。
operator的含義:+?增加權限。-取消權限。=?設定權限。
permission的含義:r讀權限。w寫權限。x?執行權限。s?文件屬主和組set -ID。t?粘性位*。l?給文件加鎖,使其他用戶無法訪問。
u,g,o ? 針對文件屬主、同組用戶及其他用戶的操作。
其中mode是一個八進制數:
0400 文件屬主可讀 ? ? ? ?0040 同組用戶可讀 ? ? ? ? ?0004?其他用戶可讀
0200 文件屬主可寫 ? ? ? ?0020 同組用戶可寫 ? ? ? ? ?0002?其他用戶可寫
0100 文件屬主可執行 ? ?0010 同組用戶可執行 ? ? ? 0001?其他用戶可執行
myfile文件具有這樣的權限:
? rw- ? ? ? ? r-- ? ? ? ? r--
? 4+2 ? ? ? ?4 ? ? ? ? 4
把相應權限位所對應的值加在一起,就是644。
4.chown和chgrp
chown命令的一般形式為:
chown?-R -h owner file
- R選項意味著對所有子目錄下的文件也都進行同樣的操作。
?- h選項意味著在改變符號鏈接文件的屬主時不影響該鏈接所指向的目標文件。
如:
$ chown MySQL hiscore 把 hiscore文件的屬主改為mysql
$ chown -R mysql hiscore 遞歸地把hiscore(數據庫名稱)目錄下的所有文件屬主改成mysql
chgrp命令和chown命令的格式差不多
chgrp?sybadmin?project
把project文件所屬的組由admin變為sybadmin(系統中的另外一個用戶組) 。
2. ls、find和xargs
ls使用技巧
以找到當前目錄中最大的那個文件:
ls -lSrh
“r”的作用是將大的文件列在后面,而“h”則是給出易于人們閱讀的輸出(MB或者諸如此類)。你也可以搜尋最大的MP3/MPEG文件:
ls -lSrh *.mp*
你也可以通過下面這條命令搜尋最大的目錄:
du -kx | egrep -v "\./.+/" | sort -n
Find命令的一般形式為:
find pathname -options [-print -exec -ok]讓我們來看看該命令的參數:
? ??pathname?? find命令所查找的目錄路徑。例如用.來表示當前目錄,用/來表示系統根目錄。
? ?-options?? ? ?為命令選項
? ?-print ??? ? ? ? find命令將匹配的文件輸出到標準輸出。
???-exec ??? ? ? find命令對匹配的文件執行該參數所給出的 shell命令。相應命令的形式為 ' comm -and' {} \;,注意{ }和\;之間的空格。
? ?-ok?? 和-exec的作用相同,只不過以一種更為安全的模式來執行該參數所給出的 shell命令, 在執行每一個命令之前,都會給出提示,讓用戶來確定是否執行。
1.??find命令選項
? ?-name?? 按照文件名查找文件。?? -perm?? 按照文件權限來查找文件。
???-prune?? 使用這一選項可以使find命令不在當前指定的目錄中查找, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?如果同時使用了-depth選項,那么-prune選項將被find命令忽略。
???-user?? 按照文件屬主來查找文件。
???-group?? 按照文件所屬的組來查找文件。
???-mtime?? -n +n ? 按照文件的更改時間來查找文件,
? ? ? ? ? ? ? ? - n表示文件更改時間距現在n天以內,+ n表示文件更改時間距現在n天以前。?
? ? ? ? ? ? ? ? find命令還有- atime和-ctime選項,但它們都和-mtime選項相似,所以我們在這里只介紹- mtime選項。
? ?-nogroup?? 查找無有效所屬組的文件,即該文件所屬的組在 /etc/groups中不存在。
???-nouser?? 查找無有效屬主的文件,即該文件的屬主在 /etc/passwd中不存在。
???-newer file1 ! file2 ??查找更改時間比文件file1新但比文件file2舊的文件。
???-type?? 查找某一類型的文件,諸如:
? ?b -?塊設備文件。
???d -?目錄。
? ?c -?字符設備文件。
???p -?管道文件。
???l -?符號鏈接文件。
???f -?普通文件。
??-size n[c]?? 查找文件長度為n塊的文件,帶有c時表示文件長度以字節計。
??-depth ??在查找文件時,首先查找當前目錄中的文件,然后再在其子目錄中查找。
??-fstype?? 查找位于某一類型文件系統中的文件,這些文件系統類型通常可以在配置文件/etcfstab中找到,該配置文件中包含了本系統中有關文件系統的信息。
???-mount ??在查找文件時不跨越文件系統mount點。
?? -follow?? 如果find命令遇到符號鏈接文件,就跟蹤至鏈接所指向的文件。
? ?-cpio?? 對匹配的文件使用cpio命令,將這些文件備份到磁帶設備中。
2. find的例子:
1)匹配$ H O M E目錄下的所有文件,下面兩種方法都可以使用:$ find $HOME -print
$ find ~ -print
2) 在當前目錄中查找suid置位,文件屬主具有讀、寫、執行權限,并且文件所屬組的用戶和其他用戶具有讀和執行的權限的文件,可以用:
$ find . -type f -perm 4755 -print
3 )查找系統中所有文件長度為0的普通文件,并列出它們的完整路徑,可以用:
? ? ? ? $ find / -type f -size 0 -exec ls -l {} \;
可以按照文件長度來查找文件,這里所指的文件長度既可以用塊(block)來計量,也可以用字節來計量。以字節計量文件長度的表達形式為N?c;以塊計量文件長度只用數字表示即可。??
在按照文件長度查找文件時,一般使用這種以字節表示的文件長度,在查看文件系統的大小,因為這時使用塊來計量更容易轉換。??
實例1:在當前目錄下查找文件長度大于1?M字節的文件??
命令:
find?.?-size?+1000000c?-print
實例2:在/home/apache目錄下查找文件長度恰好為100字節的文件:??
命令:
find?/home/apache?-size?100c?-print??
實例3:在當前目錄下查找長度超過10塊的文件(一塊等于512字節)?
命令:
find?.?-size?+10?-print
$ find /var/logs -type f -mtime +7 -exec rm {} \;
5) 查找系統中所有屬于audit組的文件,可以用:
$find /-name -group audit -print
6) 我們的一個審計系統每天創建一個審計日志文件。日志文件名的最后含有數字,這樣我們一眼就可以看出哪個文件是最新的,哪個是最舊的。 admin.log文件編上了序號:
admin.log.001、admin.log.002等等。下面的find命令將刪除/logs目錄中訪問時間在7日以前、含有數字后綴的admin.log文件。該命令只檢查三位數字,所以相應日志文件的后綴不要超過999。
$ find /logs -name 'admin.log[0-9][0-9][0-9] '-atime +7 -exec rm {} \;
7) 查找當前文件系統中的所有目錄并排序,可以用:
$ find . -type d -print -local -mount |sort
8) 查找系統中所有的rmt磁帶設備,可以用:
$ find /dev/rmt -print
9)從根目錄開始查找所有擴展名為.log的文本文件,并找出包含”ERROR”的行:
$?find / -type f -name "*.log" | xargs grep "ERROR"?
10、使用find在多個文件中替換掉相同的文本
要替換當前目錄以及下層目錄里所有文件中的Windows為Linux,你可以這樣運行:
find . -name '*.txt' -print | xargs perl -pi -e's/Windows/Linux/ig' *.txt
或者如果你更需要讓它只作用于普通文件上
find -type f -name '*.txt' -print0 | xargs --null perl -pi -e 's/Windows/Linux/'
3. 后臺執行命令
1. crontab
1). crontab的域是crontab的格式:
分 ?時 ?日 ?月 ?星期 要運行的命令
第1列 分鐘1~59
第2列 小時1~23(0表示子夜)
第3列 日1~31
第4列 月1~12
第5列 星期0~6(0表示星期天)
第6列 要運行的命令
crontab文件的一個條目是從左邊讀起的,第一列是分,最后一列是要運行的命令,它位于星期的后面。
用橫杠-來表示一個時間范圍,例如你希望星期一至星期五運行某個作業,那么可以在星期域使用1-5來表示。
使用逗號“,” ,例如你希望星期一和星期四運行某個作業,只需要使用 1,4來表示。
用星號 *來表示連續的時間段。如果你對某個表示時間的域沒有特別的限定,也應該在該域填入 *。
該文件的每一個條目必須含有 5個時間域,而且每個域之間要用空格分隔。該文件中所有的注釋行要在行首用#來表示。
例子:
分 時 日 月 星期 要運行的命令
30 21 * ? * ?* ? /apps/bin/cleanup.sh :表示每晚的21:30運行/apps/bin目錄下的cleanup.sh。
45 4 ?1,10,22 * * /apps/bin/backup.sh :表示每月1、10、22日的4:45運行/apps/b i n目錄下的backup.sh。
10 1 * * 6,0 /bin/find -name "core" -exec rm {} \; :表示每周六、周日的1 : 1 0運行一個f i n d命令。
0,30 18-23 * * * /apps/bin/dbcheck.sh:表示在每天18:00至23:00之間每隔30分鐘運行/apps/bin目錄下的dbcheck.sh。
0 23 * * 6 /apps/bin/qtrend.sh :表示每星期六的11:00pm運行/apps/bin目錄下的qtrend.sh。
每隔30分鐘時運行:
*/30?* * ? * ?* ? /apps/bin/cleanup.sh :
2) 創建和提交crontab文件:
創建一個名為davecron。的文件,加入如下的內容:
#15 minutes between 6pm and 6am
0,15,30,45 18-06 * * * ?/bin/echo `date` > /dev/console
系統將每隔 15分鐘向控制臺輸出一次當前時間。
如果系統崩潰或掛起,從最后所顯示的時間就可以一眼看出系統是什么時間停止工作的。
提交crontab文件,cron命令的參數:
$ crontab davecron
現在該文件已經提交給cron進程,它將每隔1 5分鐘運行一次。
同時,新創建文件的一個副本已經被放在/var/spool/cron目錄中,文件名就是用戶名davecron。
2) 常用參數:
crontab -e ?//編輯當前用戶的定時任務
crontab -u ?linuxso ?-e ?//編輯用戶linuxso的定時任務
crontab -r ? //刪除crontab文件
注意:編輯crontab文件,最好先選擇好編輯器,選vim(3):
update-alternatives --config editor
[plain] view plaincopyprint?3) $HOME目錄中對crontab文件做一備份:
$crontab -l > $HOME/mycron
4) 恢復丟失的crontab文件:
如果不小心誤刪了crontab文件,假設你在自己的$HOME目錄下還有一個備份,那么可以將其拷貝到/var/spool/cron/<username>,其中<username>是用戶名。如果由于權限問題無法完
成拷貝,可以用:
$ crontab <filename>
其中,<filename>是你在$HOME目錄中副本的文件名。
我建議你在自己的$HOME目錄中保存一個該文件的副本。我就有過類似的經歷,有數次誤刪了crontab 文件(因為r鍵緊挨在e鍵的右邊…) 。這就是為什么有些系統文檔建議不要直接
編輯crontab 文件,而是編輯該文件的一個副本,然后重新提交新的文件。
有些crontab 的變體有些怪異,所以在使用crontab 命令時要格外小心。如果遺漏了任何選
項,crontab 可能會打開一個空文件,或者看起來像是個空文件。這時敲crontab 鍵退出,不要按
< Ctrl - D >,否則你將丟失crontab 文件。
查看crontab服務狀態:service crond status
手動啟動crontab服務:service crond start
2. at命令提交命令或者shell腳本
1)at命令使用:at命令允許用戶向cron守護進程提交作業,使其在稍后的時間運行。這里稍后的時間可能是指10min以后,也可能是指幾天以后。如果你希望在一個月或更長的時間以后運行,最好還是使用crontab文件。一旦一個作業被提交, at命令將會保留所有當前的環境變量,包括路徑,不象crontab,只提供缺省的環境。該作業的所有輸出都將以電子郵件的形式發送給用戶,除非你對其輸出進行了重定向,絕大多數情況下是重定向到某個文件中。和crontab一樣,根用戶可以通過/etc目錄下的at.allow和at.deny文件來控制哪些用戶可以使用at命令,哪些用戶不行。不過一般來說,對at命令的使用不如對crontab的使用限制那么嚴格。
at命令的基本形式為:
at [-f script] [-m -l -r] [time] [date]
其中,
-f script 是所要提交的腳本或命令。
-l 列出當前所有等待運行的作業。at q命令具有相同的作用。
-r 清除作業。為了清除某個作業,還要提供相應的作業標識(ID);有些UNIX變體只接受atrm作為清除命令。
-m 作業完成后給用戶發郵件。
time at命令的時間格式非常靈活:
1) 可以是H、HH.HH MM、HH : MM或H:M,其中H和M分別是小時和分鐘。還可以使用a.m.或p.m.。
2)date日期格式可以是月份數或日期數,而且at命令還能夠識別諸如today、tomorrow這樣的詞。現在就讓我們來看看如何提交作業。
2)使用at命令提交命令或腳本
使用at命令提交作業有幾種不同的形式,可以通過命令行方式,也可以使用at命令提示符。
一般來說在提交若干行的系統命令時,我使用at命令提示符方式,而在提交s h e l l腳本時,使用命令行方式。
如果你想提交若干行的命令,可以在at命令后面跟上日期/時間并回車。然后就進入了at命令提示符,這時只需逐條輸入相應的命令,然后按‘ <CTRL - D>’退出。下面給出一個例子:
root@ubuntu:/home/hadoop/testsh# at 16:10
warning: commands will be executed using /bin/sh
at> find /etc -name "passwd" -print
at> <EOT>
at> job 1 at 2012-10-22 16:10 ? ??
其中,?
<EOT>就是<CTRL - D>。在16:10 ?系統將執行一個簡單的find命令。
你應當已經注意到,我所提交的作業被分配了一個唯一標識job 1。該命令在完成以后會將全部結果以郵件的形式發送給我。
如果希望向at命令提交一個shell腳本,使用其命令行方式即可。在提交腳本時使用- f選項。
$ at 3.00pm tomorrow -f /apps/bin/db_table.sh
warning: commands will be executed using /bin/sh
job 8 at 2012-10-23 15:00
在上面的例子中,一個叫做db_table.sh的腳本將在明天下午3:00運行。
還可以使用echo命令向at命令提交作業:
$ echo find /etc -name "passwd" -print | at now +1 minute
4. shell輸入與輸出
1 . echo?
字符串被重定向到一個名為myfile文件中:
$ echo "The log files have all been done"> myfile
2 . read?
可以使用read 語句從鍵盤或文件的某一行文本中讀入信息,并將其賦給一個變量。如果只
指定了一個變量,那么read 將會把所有的輸入賦給該變量,直至遇到第一個文件結束符或回
車。
它的一般形式為:
read varible1 varible2 ...
只指定了一個變量,它將被賦予直至回車之前的所有內容:
root@ubuntu:/home/testsh# read name
test1
root@ubuntu:/home/testsh# echo $name
test1
root@ubuntu:/home/testsh#?
3 . cat
顯示myfile1、myfile2、myfile3這三個文件,可以用:
$ cat myfile1 myfile2 myfile3
4 . 管道
格式:命令1 |命令2
其中|是管道符號。
sed、awk和grep都很適合用管道,特別是在簡單的一行命令中。在下面的例子中, who命令的輸出通過管道傳遞給awk命令,以便只顯示用戶名和所在的終端。
root@ubuntu:/home/testsh# who |awk '{print $1 "\t" $2}'
hgs?ptty7
hgs?pts/0
root@ubuntu:/home/testsh#?
5. tee
它的一般形式為:
tee -a files
其中,- a表示追加到文件末尾。
當執行某些命令或腳本時,如果希望把輸出保存下來, tee命令非常方便。
我們使用 who命令,結果輸出到屏幕上,同時保存在 who.out文件中:
root@ubuntu:/home/testsh# who | tee who.out
hgs ? tty7 ? ? ? ? 2011-10-21 23:26 (:0)
hgs ? pts/0 ? ? ? ?2011-10-21 23:26 (:0.0)
root@ubuntu:/home/testsh# ls
devcont ?devcront ?who.out
root@ubuntu:/home/testsh# cat who.out?
hgs ? tty7 ? ? ? ? 2011-10-21 23:26 (:0)
hgs?? pts/0 ? ? 2011-10-21 23:26 (:0.0)
6.重定向
command > filename 把把標準輸出重定向到一個新文件中
command >> filename 把把標準輸出重定向到一個文件中(追加)
command 1 > fielname 把把標準輸出重定向到一個文件中
command > filename 2>&1 把把標準輸出和標準錯誤一起重定向到一個文件中
command 2 > filename 把把標準錯誤重定向到一個文件中
command 2 >> filename 把把標準輸出重定向到一個文件中(追加)
command >> filename 2>&1 把把標準輸出和標準錯誤一起重定向到一個文件中 (追加)
command < filename >filename2 把command命令以filename文件作為標準輸入,以 filename 2文件作為標準輸出
command < filename 把command命令以filename文件作為標準輸入
command << delimiter 把從標準輸入中讀入,直至遇到delimiter分界符
command <&m 把把文件描述符m作為標準輸入
command >&m 把把標準輸出重定向到文件描述符m中
command <&- 把關閉標準輸入
5. grep功能
grep選項
常用的grep選項有:
-c ? 只輸出匹配行的計數。
-i ? 不區分大小寫(只適用于單字符) 。
-h ? 查詢多文件時不顯示文件名。
-l ? 查詢多文件時只輸出包含匹配字符的文件名。
-n ? 顯示匹配行及行號。
-s ? 不顯示不存在或無匹配文本的錯誤信息。
-v ? 顯示不包含匹配文本的所有行。
1)如果要在當前目錄下所有.doc文件中查找字符串“sort” ,方法:$ grep "sort"*.doc
2)從文件內容查找匹配指定字符串的行:$ grep "被查找的字符串" 文件名?
3)從文件內容查找與正則表達式匹配的行:$ grep –e “正則表達式” 文件名?
4)查找時不區分大小寫:$ grep –i "被查找的字符串" 文件名?
5)查找匹配的行數:$ grep -c "被查找的字符串" 文件名?
6)從文件內容查找不匹配指定字符串的行:$ grep –v "被查找的字符串" 文件名?
7)遞歸查找目錄/etc/apache2下的文件內容“"\/var\/www”:grep "\/var\/www" -i /etc/apache2 -r?
6. awk功能
1. awk簡單使用:awk '{print $0}' grade.txt > wow
2. awk過濾access.log日志
[plain] view plaincopyprint?
7. 查看文件內容:head,tail,sed
相信最基本的cat、more和less你已經很熟悉了,如果有特殊的要求呢:1. 如果你只想看文件的前5行,可以使用head命令,如:
head -5 /etc/passwd
2. 如果你想查看文件的后10行,可以使用tail命令,如:
tail -2 /etc/passwd 或 tail -n 2 /etc/passwd
tail -f /var/log/messages
參數-f使tail不停地去讀最新的內容,這樣有實時監視的效果,用Ctrl+c來終止!
3. 查看文件中間一段,你可以使用sed命令,如:
sed -n '5,10p' /etc/passwd
這樣你就可以只查看文件的第5行到第10行。
tail語法格式:
? ? tail [ -f ] [ -c Number | -n Number | -m Number | -b Number | -k Number ] [ File ]
或者
tail [ -r ] [ -n Number ] [ File ]
使用說明:
tail 命令從指定點開始將 File 參數指定的文件寫到標準輸出。如果沒有指定文件,則會使用標準輸入。 Number 變量<br />指定將多少單元寫入標準輸出。 Number 變量的值可以是正的或負的整數。如果值的前面有 +(加號),從文件開頭<br />指定的單元數開始將文件寫到標準輸出。如果值的前面有 -(減號),則從文件末尾指定的單元數開始將文件寫到<br />標準輸出。如果值前面沒有 +(加號)或 -(減號),那么從文件末尾指定的單元號開始讀取文件。
主要參數:
-b Number 從 Number 變量表示的 512 字節塊位置開始讀取指定文件。?
-c Number 從 Number 變量表示的字節位置開始讀取指定文件。?
-f 如果輸入文件是常規文件或如果 File 參數指定 FIFO(先進先出),那么 tail?
命令不會在復制了輸入文件的最后的指定單元后終止,而是繼續從輸入文件讀取和復
制額外的單元(當這些單元可用時)。如果沒有指定 File 參數,并且標準輸入是管道
則會忽略 -f 標志。tail -f 命令可用于監視另一個進程正在寫入的文件的增長。?
-k Number 從 Number 變量表示的 1KB 塊位置開始讀取指定文件。?
-m Number 從 Number 變量表示的多字節字符位置開始讀取指定文件。使用該標志提供
在單字節和雙字節字符代碼集環境中的一致結果。?
-n Number 從首行或末行位置來讀取指定文件,位置由 Number 變量的符號(+ 或 - 或無)
表示,并通過行號 Number 進行位移。?
-r 從文件末尾以逆序方式顯示輸出。
-r 標志的缺省值是以逆序方式顯示整個文件。
如果文件大于 20,480 字節,那么-r標志只顯示最后的 20,480 字節。?
-r 標志只有與 -n 標志一起時才有效。否則,就會將其忽略
7. sed和awk的常用實例
一、文本間隔
1、在每一行后面增加一空行
sed G guo.sh
awk '{printf("%s\n\n",$0 ) }'
2、將文件中原來的空行刪掉,并在在每一行后邊增加一空行
sed '/^$/d;G '
awk '!/^$/ {printf("%s\n\n",$0 ) }'
3在匹配式樣的行前插入一空行
sed '/good/i\\'
sed '/hello/{x;p;x;}'
awk '{ if(/hello/) printf("\n\%s\n",$0);else print $0}'
4、在匹配式樣的行后插入一空行
sed '/good/a\\'
sed '/hello/G'
awk '{if(/hello/) printf("%s\n\n",$0) ;else print $0}'
5、在匹配式樣的行前、行后各插入一空行
sed '/hello/{x;p;x;G;}'
awk '{ if(/hello/) printf("\n\%s\n\n",$0);else print $0}'
二、文本的替換
1、在每一行查找到good,然后把good替換為bad
sed 's/good/bad/'只把每行的第一個good替換為bad
sed 's/good/bad/2'只把每行的第二個good替換為bad
sed 's/good/bad/g'把每一行的所有good替換為bad
sed 's/.?good/\1bad/'只把每一行的的最后一個good替換位bad
sed 's/.?good.?good/\1bad\2/'只把每一行的的倒數第二個good替換位bad
awk ? '{sub(/good/,"bad"); print $0}'只把每行的第一個good替換為bad
awk ? '{gsub(/good/,"bad"); print $0}'把每一行的所有good替換為bad
cat ?test |tr 'root' 'good'
cat ? ?test |tr 'root' 'god'
sed ? 's/root/good/p' test
awk ? '{gsub(/root/,"good");print $0}' test
awk ? '{gsub(/root/,"god");print $0}' test
通過對比可知tr的替換兩個字串必須等長度,而sed不能把說有的root替換
2、只在出現字符串fell字符串的前提下,將找到的行中的good替換為bad
sed ?'/fell/ s/good/bad/g'
awk ? '{if(/fell/) gsub(/good/,"bad"); print $0 }'
3、只在不出現字符串fell字符串的前提下,將找到的行中的good替換為bad
sed '/fell/ !s/good/bad/g'
awk '{if(!/fell/) gsub(/good/,"bad"); print $0 }'
4、不管是good、fell還是sun,一路替換為bad
sed 's/good/bad/g;s/fell/bad/g;s/sun/bad/g'
sed 's/good\|fell\|sun/bad/g'
awk '{gsub(/good|fell|sun/,"bad") ; print $0}'
5、倒置所有行,第一行變為最后一行(模擬tac)
sed '1!G;h;$!d'
sed -n '1!G;h;$p'
awk '{A[i++]=$0} END{for (j=i-1;j>=0;j--) print A[j]}'
6、將每兩行連接為一行
sed '$!N;s/\n/ /'
awk '{f=!f;if(!f) printf("%s",$0);else printf("%s\n",$0)}'
7、在文件中每隔5行顯示一空行
sed '0~5G'
sed 'n;n;n;n;G'
awk '{print $0 ;i++;if(i==5) {printf( "\n") ;i=0}}'
三、選擇性的顯示特定行
1、顯示文件的前10行
sed10q
awk '{print ;if(NR==10) exit }'
2、顯示文件的第一行
sed q
awk '{ print;exit}'
3、顯示文件的倒數第二行
sed -e '$!{h;d;}' -e x當文件只有一行時,輸出空行
sed -e '1{$q;}' -e '$!{h;d;}' -e x當文件只有一行時,顯示該行
sed -e '1{$d;}' -e '$!{h;d;}' -e x當文件只有一行時,不輸出
awk '{ B=A;A=$0} END{ print B}'當文件只有一行時,輸出空行
4、只顯示匹配正則表達式的行
sed -n '/good/p'
sed ?'/good/!d'
awk '/good/ {print $0}'
awk '/good/'
grep 'good'
5、只顯示不匹配正則表達式的行
sed -n '/good/!p'
sed '/good/d'
awk '!/good/ {print $0}'
grep -v 'good'
6、顯示匹配行的上一行,而不顯示匹配行
sed -n '/good/{g;1!p;};h'
awk '/good/ {print A} {A=$1}
7、顯示匹配行的下一行,而不顯示匹配行
sed -n '/good/{n;p;}'
awk '{if(A) print;A=0}/23/{A=1}'
8、顯示文本的制定行
sed -n '3,5p'
sed '3,5!d'
awk '{if(NR>=3 &&NR<=5) print } '
目錄: 1、不顯示文件中的空行 2、刪除文件的1到5行3、刪除文件注釋行4、打印匹配行5、顯示從字符1到字符2的中間行6、匹配特別表達式7、替代文本
1、不顯示文件中的空行
[guo@guo~]$ grep -v '^$' rc.local
[guo@guo~]$ sed -e '/^$/d' rc.local
[guo@guo~]$ awk '!/^$/{print $0 }' rc.local
2、刪除文件的1到5行
[guo@guo~]$ cat test
[guo@guo~]$ sed -e '1,5d' test
[guo@guo~]$ awk '{if(NR>5 ) print $0} ' test
3、刪除文件注釋行
[guo@guo~]$ sed -e "/^#/d" rc.local
[guo@guo~]$ awk '!/^#/{print $0}' rc.local
[guo@guo~]$ grep -v '^#' rc.local
5、顯示從字符1到字符2的中間行
[guo@guo~]$ sed -n -e '/hello/,/sorry/p' test1
[guo@guo~]$ awk '/hello/,/sorry/ {print $0 }' test1
6、匹配特別表達式
[guo@guo~]$ sed -n -e '/main[[:space:]]*(/,/^}/p' for.c
1、通過awk訪問系統環境變量
[guo@guoawk]$ awk 'BEGIN { print ENVIRON["HOME"]; printENVIRON["PATH"]}'
/home/guo
/usr/lib/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin
2、awk中的算術運算符
[guo@guoawk]$ awk 'BEGIN {print "3+2=" 3+2 }'
3+2=5
[guo@guoawk]$ awk 'BEGIN {print "2^10=" 2^10 }'
2^10=1024
[guo@guoawk]$ awk 'BEGIN {print "(3+1)*4/2=" (3+1)*4/2}'
(3+1)*4/2=8
awk支持的運算符有+ - * / % ^。
4、awk的循環
if語句
[guo@guoawk]$ cat num
12243535
890232
232 9809
890 -8990
[guo@guoawk]$ awk '{if($1>$2) print $0}' num
890232
890 -8990
[guo@guoawk]$ awk '{if($1>$2) {print $0 ; print $1 "is larger than"$2}}' num
890232
890islarger than232
890 -8990
890islarger than-8990
if/else
[guo@guoawk]$ awk '{if($1>$2) print $1 ;else print $2}' num
3535
890
9809
890
[guo@guoawk]$ awk '{if($1>$2) {count++ ;print count} else print $2}' num
3535
1
9809
2
# 在每一行后面增加一空行
sed G
# 將原來的所有空行刪除并在每一行后面增加一空行。
# 這樣在輸出的文本中每一行后面將有且只有一空行。
sed '/^$/d;G'
?# 在每一行后面增加兩行空行
sed 'G;G'
# 將第一個腳本所產生的所有空行刪除(即刪除所有偶數行)
sed 'n;d'
?
# 在匹配式樣“regex”的行之前插入一空行
sed '/regex/{x;p;x;}'
# 在匹配式樣“regex”的行之后插入一空行
sed '/regex/G'
# 在匹配式樣“regex”的行之前和之后各插入一空行
sed '/regex/{x;p;x;G;}'
編號:
--------
# 為文件中的每一行進行編號(簡單的左對齊方式)。這里使用了“制表符”
# (tab,見本文末尾關于'\t'的用法的描述)而不是空格來對齊邊緣。
sed = filename | sed 'N;s/\n/\t/'
# 對文件中的所有行編號(行號在左,文字右端對齊)。
sed = filename | sed 'N; s/^/? ???/; s/ *.{6,}\n/\1??/'
# 對文件中的所有行編號,但只顯示非空白行的行號。
sed '/./=' filename | sed '/./N; s/\n/ /'
# 計算行數 (模擬 "wc -l")
sed -n '$='
sed 's/.$//'????? 將文件每行字母最后一個刪除
?
?
# 下面的腳本只對UnxUtils sed 4.0.7 及更高版本有效。要識別UnxUtils版本的
#??sed可以通過其特有的“--text”選項。你可以使用幫助選項(“--help”)看
# 其中有無一個“--text”項以此來判斷所使用的是否是UnxUtils版本。其它DOS
# 版本的的sed則無法進行這一轉換。但可以用“tr”來實現這一轉換。
sed "s/\r//" infile >outfile? ???# UnxUtils sed v4.0.7 或更高版本
tr -d \r <infile >outfile? ?? ???# GNU tr 1.22 或更高版本
# 將每一行前導的“空白字符”(空格,制表符)刪除
# 使之左對齊
sed 's/^[ \t]*//'? ?? ?? ?? ?? ? # 見本文末尾關于'\t'用法的描述
# 將每一行拖尾的“空白字符”(空格,制表符)刪除
sed 's/[ \t]*$//'? ?? ?? ?? ?? ? # 見本文末尾關于'\t'用法的描述
# 將每一行中的前導和拖尾的空白字符刪除
sed 's/^[ \t]*//;s/[ \t]*$//'
# 在每一行開頭處插入5個空格(使全文向右移動5個字符的位置)
sed 's/^/? ???/'
# 以79個字符為寬度,將所有文本右對齊
sed -e :a -e 's/^.\{1,78\}$/ &/;ta'??# 78個字符外加最后的一個空格
# 以79個字符為寬度,使所有文本居中。在方法1中,為了讓文本居中每一行的前
# 頭和后頭都填充了空格。 在方法2中,在居中文本的過程中只在文本的前面填充
# 空格,并且最終這些空格將有一半會被刪除。此外每一行的后頭并未填充空格。
sed??-e :a -e 's/^.\{1,77\}$/ & /;ta'? ?? ?? ?? ?? ?? ?? ?# 方法1
sed??-e :a -e 's/^.\{1,77\}$/ &/;ta' -e 's/?\1/\1/'??# 方法2
# 在每一行中查找字串“foo”,并將找到的“foo”替換為“bar”
sed 's/foo/bar/'? ?? ?? ?? ?? ???# 只替換每一行中的第一個“foo”字串
sed 's/foo/bar/4'? ?? ?? ?? ?? ? # 只替換每一行中的第四個“foo”字串
sed 's/foo/bar/g'? ?? ?? ?? ?? ? # 將每一行中的所有“foo”都換成“bar”
sed 's/.?foo.?foo/\1bar\2/' # 替換倒數第二個“foo”
sed 's/.?foo/\1bar/'? ?? ?? ?? ?# 替換最后一個“foo”
# 只在行中出現字串“baz”的情況下將“foo”替換成“bar”
sed '/baz/s/foo/bar/g'
# 將“foo”替換成“bar”,并且只在行中未出現字串“baz”的情況下替換
sed '/baz/!s/foo/bar/g'
# 不管是“scarlet”“ruby”還是“puce”,一律換成“red”
sed 's/scarlet/red/g;s/ruby/red/g;s/puce/red/g'??#對多數的sed都有效
gsed 's/scarlet\|ruby\|puce/red/g'? ?? ?? ?? ?? ?# 只對GNU sed有效
# 倒置所有行,第一行成為最后一行,依次類推(模擬“tac”)。
# 由于某些原因,使用下面命令時HHsed v1.5會將文件中的空行刪除
sed '1!G;h;$!d'? ?? ?? ?? ?? ?# 方法1
sed -n '1!G;h;$p'? ?? ?? ?? ? # 方法2
# 將行中的字符逆序排列,第一個字成為最后一字,……(模擬“rev”)
sed '/\n/!G;s/..?\n/&\2\1/;//D;s/.//'
# 將每兩行連接成一行(類似“paste”)
sed '$!N;s/\n/ /'
# 如果當前行以反斜杠“\”結束,則將下一行并到當前行末尾
# 并去掉原來行尾的反斜杠
sed -e :a -e '/\\$/N; s/\\\n//; ta'
# 如果當前行以等號開頭,將當前行并到上一行末尾
# 并以單個空格代替原來行頭的“=”
sed -e :a -e '$!N;s/\n=/ /;ta' -e 'P;D'
# 為數字字串增加逗號分隔符號,將“1234567”改為“1,234,567”
gsed ':a;s/\B[0-9]\{3\}\>/,&/;ta'? ?? ?? ?? ?? ?? ?? ?# GNU sed
sed -e :a -e 's/.?[0?9][0?9]{3}/\1,\2/;ta'??# 其他sed
# 為帶有小數點和負號的數值增加逗號分隔符(GNU sed)
gsed -r ':a;s/(^|[^0-9.])([0-9]+)([0-9]{3})/\1\2,\3/g;ta'
# 在每5行后增加一空白行 (在第5,10,15,20,等行后增加一空白行)
gsed '0~5G'? ?? ?? ?? ?? ?? ?? ? # 只對GNU sed有效
sed 'n;n;n;n;G;'? ?? ?? ?? ?? ???# 其他sed
選擇性地顯示特定行:
--------
# 顯示文件中的前10行 (模擬“head”的行為)
sed 10q
# 顯示文件中的第一行 (模擬“head -1”命令)
sed q
# 顯示文件中的最后10行 (模擬“tail”)
sed -e :a -e '$q;N;11,$D;ba'
# 顯示文件中的最后2行(模擬“tail -2”命令)
sed '$!N;$!D'
# 顯示文件中的最后一行(模擬“tail -1”)
sed '$!d'? ?? ?? ?? ?? ?? ?? ?? ?# 方法1
sed -n '$p'? ?? ?? ?? ?? ?? ?? ? # 方法2
# 顯示文件中的倒數第二行
sed -e '$!{h;d;}' -e x? ?? ?? ?? ???# 當文件中只有一行時,輸入空行
sed -e '1{$q;}' -e '$!{h;d;}' -e x??# 當文件中只有一行時,顯示該行
sed -e '1{$d;}' -e '$!{h;d;}' -e x??# 當文件中只有一行時,不輸出
# 只顯示匹配正則表達式的行(模擬“grep”)
sed -n '/regexp/p'? ?? ?? ?? ?? ?# 方法1
sed '/regexp/!d'? ?? ?? ?? ?? ???# 方法2
# 只顯示“不”匹配正則表達式的行(模擬“grep -v”)
sed -n '/regexp/!p'? ?? ?? ?? ???# 方法1,與前面的命令相對應
sed '/regexp/d'? ?? ?? ?? ?? ?? ?# 方法2,類似的語法
# 查找“regexp”并將匹配行的上一行顯示出來,但并不顯示匹配行
sed -n '/regexp/{g;1!p;};h'
# 查找“regexp”并將匹配行的下一行顯示出來,但并不顯示匹配行
sed -n '/regexp/{n;p;}'
# 顯示包含“regexp”的行及其前后行,并在第一行之前加上“regexp”所
# 在行的行號 (類似“grep -A1 -B1”)
sed -n -e '/regexp/{=;x;1!p;g;$!N;p;D;}' -e h
# 顯示包含“AAA”、“BBB”或“CCC”的行(任意次序)
sed '/AAA/!d; /BBB/!d; /CCC/!d'??# 字串的次序不影響結果
# 顯示包含“AAA”、“BBB”和“CCC”的行(固定次序)
sed '/AAA.*BBB.*CCC/!d'
# 顯示包含“AAA”“BBB”或“CCC”的行 (模擬“egrep”)
sed -e '/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d? ? # 多數sed
gsed '/AAA\|BBB\|CCC/!d'? ?? ?? ?? ?? ?? ?? ?? ?# 對GNU sed有效
# 顯示包含“AAA”的段落 (段落間以空行分隔)
# HHsed v1.5 必須在“x;”后加入“G;”,接下來的3個腳本都是這樣
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;'
# 顯示包含“AAA”“BBB”和“CCC”三個字串的段落 (任意次序)
sed -e '/./{H;$!d;}' -e 'x;/AAA/!d;/BBB/!d;/CCC/!d'
# 顯示包含“AAA”、“BBB”、“CCC”三者中任一字串的段落 (任意次序)
sed -e '/./{H;$!d;}' -e 'x;/AAA/b' -e '/BBB/b' -e '/CCC/b' -e d
gsed '/./{H;$!d;};x;/AAA\|BBB\|CCC/b;d'? ?? ?? ?# 只對GNU sed有效
# 顯示包含65個或以上字符的行
sed -n '/^.\{65\}/p'
# 顯示包含65個以下字符的行
sed -n '/^.\{65\}/!p'? ?? ?? ?? ?# 方法1,與上面的腳本相對應
sed '/^.\{65\}/d'? ?? ?? ?? ?? ? # 方法2,更簡便一點的方法
# 顯示部分文本??從包含正則表達式的行開始到最后一行結束
sed -n '/regexp/,$p'
# 顯示部分文本??指定行號范圍(從第8至第12行,含8和12行)
sed -n '8,12p'? ?? ?? ?? ?? ?? ? # 方法1
sed '8,12!d'? ?? ?? ?? ?? ?? ?? ?# 方法2
# 顯示第52行
sed -n '52p'? ?? ?? ?? ?? ?? ?? ?# 方法1
sed '52!d'? ?? ?? ?? ?? ?? ?? ???# 方法2
sed '52q;d'? ?? ?? ?? ?? ?? ?? ? # 方法3, 處理大文件時更有效率
# 從第3行開始,每7行顯示一次? ??
gsed -n '3~7p'? ?? ?? ?? ?? ?? ? # 只對GNU sed有效
sed -n '3,${p;n;n;n;n;n;n;}'? ???# 其他sed
# 顯示兩個正則表達式之間的文本(包含)
sed -n '/Iowa/,/Montana/p'? ?? ? # 區分大小寫方式
選擇性地刪除特定行:
--------
# 顯示通篇文檔,除了兩個正則表達式之間的內容
sed '/Iowa/,/Montana/d'
# 刪除文件中相鄰的重復行(模擬“uniq”)
# 只保留重復行中的第一行,其他行刪除
sed '$!N; /^.?\n\1$/!P; D'
# 刪除文件中的重復行,不管有無相鄰。注意hold space所能支持的緩存
# 大小,或者使用GNU sed。
sed -n 'G; s/\n/&&/; /^[??]?\n.*\n\1/d; s/\n//; h; P'
# 刪除除重復行外的所有行(模擬“uniq -d”)
sed '$!N; s/^.?\n\1$/\1/; t; D'
# 刪除文件中開頭的10行
sed '1,10d'
# 刪除文件中的最后一行
sed '$d'
# 刪除文件中的最后兩行
sed 'N;$!P;$!D;$d'
# 刪除文件中的最后10行
sed -e :a -e '$d;N;2,10ba' -e 'P;D'? ?# 方法1
sed -n -e :a -e '1,10!{P;N;D;};N;ba'??# 方法2
# 刪除8的倍數行
gsed '0~8d'? ?? ?? ?? ?? ?? ?? ?? ?? ?# 只對GNU sed有效
sed 'n;n;n;n;n;n;n;d;'? ?? ?? ?? ?? ? # 其他sed
# 刪除匹配式樣的行
sed '/pattern/d'? ?? ?? ?? ?? ?? ?? ? # 刪除含pattern的行。當然pattern
? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?# 可以換成任何有效的正則表達式
# 刪除文件中的所有空行(與“grep '.' ”效果相同)
sed '/^$/d'? ?? ?? ?? ?? ?? ?? ?? ?? ?# 方法1
sed '/./!d'? ?? ?? ?? ?? ?? ?? ?? ?? ?# 方法2
# 只保留多個相鄰空行的第一行。并且刪除文件頂部和尾部的空行。
# (模擬“cat -s”)
sed '/./,/^$/!d'? ?? ???#方法1,刪除文件頂部的空行,允許尾部保留一空行
sed '/^$/N;/\n$/D'? ?? ?#方法2,允許頂部保留一空行,尾部不留空行
# 只保留多個相鄰空行的前兩行。
sed '/^$/N;/\n$/N;//D'
# 刪除文件頂部的所有空行
sed '/./,$!d'
# 刪除文件尾部的所有空行
sed -e :a -e '/^\n*$/{$d;N;ba' -e '}'??# 對所有sed有效
sed -e :a -e '/^\n*$/N;/\n$/ba'? ?? ???# 同上,但只對 gsed 3.02.*有效
# 刪除每個段落的最后一行
sed -n '/^$/{p;h;};/./{x;/./p;}'
特殊應用:
--------
# 移除手冊頁(man page)中的nroff標記。在Unix System V或bash shell下使
# 用'echo'命令時可能需要加上 -e 選項。
sed "s/.`echo \\\b`//g"? ? # 外層的雙括號是必須的(Unix環境)
sed 's/.^H//g'? ?? ?? ?? ? # 在bash或tcsh中, 按 Ctrl-V 再按 Ctrl-H
sed 's/.\x08//g'? ?? ?? ???# sed 1.5,GNU sed,ssed所使用的十六進制的表示方法
# 提取新聞組或 e-mail 的郵件頭
sed '/^$/q'? ?? ?? ?? ?? ? # 刪除第一行空行后的所有內容
# 提取新聞組或 e-mail 的正文部分
sed '1,/^$/d'? ?? ?? ?? ???# 刪除第一行空行之前的所有內容
# 從郵件頭提取“Subject”(標題欄字段),并移除開頭的“Subject:”字樣
sed '/^Subject: */!d; s///;q'
# 從郵件頭獲得回復地址
sed '/^Reply-To:/q; /^From:/h; /./d;g;q'
# 獲取郵件地址。在上一個腳本所產生的那一行郵件頭的基礎上進一步的將非電郵
# 地址的部分剃除。(見上一腳本)
sed 's/ *(.*)//; s/>.*//; s/.*[:<] *//'
# 在每一行開頭加上一個尖括號和空格(引用信息)
sed 's/^/> /'
# 將每一行開頭處的尖括號和空格刪除(解除引用)
sed 's/^> //'
# 移除大部分的HTML標簽(包括跨行標簽)
sed -e :a -e 's/<[^>]*>//g;/</N;//ba'
# 將分成多卷的uuencode文件解碼。移除文件頭信息,只保留uuencode編碼部分。
# 文件必須以特定順序傳給sed。下面第一種版本的腳本可以直接在命令行下輸入;
# 第二種版本則可以放入一個帶執行權限的shell腳本中。(由Rahul Dhesi的一
# 個腳本修改而來。)
sed '/^end/,/^begin/d' file1 file2 ... fileX | uudecode? ?# vers. 1
sed '/^end/,/^begin/d' "$@" | uudecode? ?? ?? ?? ?? ?? ???# vers. 2
# 將文件中的段落以字母順序排序。段落間以(一行或多行)空行分隔。GNU sed使用
# 字元“\v”來表示垂直制表符,這里用它來作為換行符的占位符??當然你也可以
# 用其他未在文件中使用的字符來代替它。
sed '/./{H;d;};x;s/\n/={NL}=/g' file | sort | sed '1s/={NL}=//;s/={NL}=/\n/g'
gsed '/./{H;d};x;y/\n/\v/' file | sort | sed '1s/\v//;y/\v/\n/'
# 分別壓縮每個.TXT文件,壓縮后刪除原來的文件并將壓縮后的.ZIP文件
# 命名為與原來相同的名字(只是擴展名不同)。(DOS環境:“dir /b”
# 顯示不帶路徑的文件名)。
echo @echo off >zipup.bat
dir /b *.txt | sed "s/^.?\.TXT/pkzip -mo \1 \1.TXT/" >>zipup.bat
總結
以上是生活随笔為你收集整理的《Linux与unix Shell编程指南》 总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 作业、进程、线程
- 下一篇: Linux系统结构 详解