1. 程式人生 > >SHELL指令碼和Sed等工具的使用

SHELL指令碼和Sed等工具的使用

SHELL指令碼(重點 )

建立shell指令碼
第一步:使用文字編輯器來建立文字檔案
第一行必須包括shell宣告序列:#!

.#!/bin/bash
添加註釋
註釋以#開頭
第二步:執行指令碼
給予執行許可權,在命令列上指定指令碼的絕對或相對路徑
直接執行直譯器,將指令碼作為直譯器程式的引數執行
指令碼規範
指令碼程式碼開頭約定
1、第一行一般為呼叫使用的語言
2、程式名,避免更改檔名為無法找到正確的檔案
3、版本號
4、更改後的時間
5、作者相關資訊
6、該程式的作用,及注意事項
7、最後是各版本的更新簡要說明
shell指令碼示例

#!/bin/bash  
#------------------------------------------    
#Filename: hello.sh #Revision: 1.1 #Date: 2011/06/01 #Author: luhao #Email: [email protected] #Website: https://blog.csdn.net/weixin_43551152 #Description: This is the first script #------------------------------------------ #Copyright: 2011 #License: GPL echo “hello world”

.vimrc檔案在根目錄下,修改:vim .vimrc 檔案


可以修改vim的指令碼註釋作者等資訊


區域性變數

變數賦值:name=‘value’
可以使用引用value:
(1) 可以是直接字串; name=“root”
(2) 變數引用:name="$USER"

(3) 命令引用:name=COMMAND name= ( C O M M

A N D ) (COMMAND) 變數引用: {name} $name
“”:弱引用,其中的變數引用會被替換為變數值

’ ':強引用,其中的變數引用不會被替換為變數值,而保持原字串
顯示已定義的所有變數:set
刪除變數:unset name
環境變數
變數宣告、賦值:
export name=VALUE
declare -x name=VALUE
變數引用:$name, ${name}
顯示所有環境變數:
env

printenv
export
declare -x
刪除變數:
unset name
退出狀態
程序使用退出狀態來報告成功或失敗
0 代表成功,1-255代表失敗
$? 變數儲存最近的命令退出狀態
例如:
ping-c1-W1hostdown&>/dev/null
echo$?


算術運算

bash中的算術運算:help let
+, -, *, /, %取模(取餘), **(乘方)
實現算術運算:
(1) let var=算術表示式
(2) var= [ ] ( 3 ) v a r = [算術表示式] (3) var= ((算術表示式))
(4) var= ( e x p r a r g 1 a r g 2 a r g 3... ) ( 5 ) d e c l a r e i v a r = ( 6 ) e c h o b c b a s h (expr arg1 arg2 arg3 ...) (5) declare –ivar= 數值 (6) echo ‘算術表示式’ | bc 乘法符號有些場景中需要轉義,如* bash有內建的隨機數生成器: RANDOM(0-32767)
echo [ [ RANDOM%50] :0-49之間隨機數
增強型賦值:
+=, -=, *=, /=, %=
let varOPERvalue
例如:let count+=3
自加3後自賦值
自增,自減:
例子:

let var+=1  
let var++  
let var-=1  
let var--  
let n=1+2  
echo $n  
3  
n=$(2+3)  
2  
expr 3+4  錯誤  
expr 3 + 4  
7  
expr為命令  3+4為引數之間要有空格************************************  
echo $[RANDOM%100+1] 取1-100之間的隨機數 **  
RANDOM為隨機數,除以100得到的餘數為0-99,+1後為1-100 *****  
echo $? 查詢命令執行結果  

& 與 交集
| 或 並集
! 非
^ 異或 相同為0 不同為1
&& 短路與 兩條命令,第一條為真,則執行第二天2條看真假,第一條為假的情況下直接不執行命令
|| 短路或 兩條命令,第一條為假,則執行第二天2條看真假,第一條為真的情況下直接不執行命令
同或 相同為1 不同為0

[ “ s t r 1 " ! = " str1" !=" str2” ] 判斷兩個字串是否相同
bash +x 加sh指令碼可以看到指令碼執行的過程,可以檢查哪裡出錯
export +定義的變數可使該變數在子程序中也生效
find -name +檔名 查詢檔案或者安裝包


bash的數值測試

-v VAR  
變數VAR是否設定  
數值測試:  
-gt是否大於  
-ge是否大於等於  
-eq是否等於  
-ne是否不等於  
-lt是否小於  
-le是否小於等於  
Bash的檔案屬性測試  

檔案大小測試:

-s FILE: 是否存在且非空
檔案是否開啟:
-t fd: fd檔案描述符是否在某終端已經開啟
-N FILE:檔案自從上一次被讀取之後是否被修改過
-O FILE:當前有效使用者是否為檔案屬主
-G FILE:當前有效使用者是否為檔案屬組
Bash的檔案測試

存在性測試

-a FILE:同-e
-e FILE: 檔案存在性測試,存在為真,否則為假
存在性及類別測試
-b FILE:是否存在且為塊裝置檔案
-c FILE:是否存在且為字元裝置檔案
-d FILE:是否存在且為目錄檔案
-f FILE:是否存在且為普通檔案
-h FILE 或-L FILE:存在且為符號連結檔案
-p FILE:是否存在且為命名管道檔案
-S FILE:是否存在且為套接字檔案


使用read命令來接受輸入
使用read來把輸入值分配給一個或多個shell變數
-p指定要顯示的提示
-s 靜默輸入,一般用於密碼
-n N指定輸入的字元長度N
-d‘字元’ 輸入結束符
-t N TIMEOUT為N秒
read從標準輸入中讀取值,給每個單詞分配一個變數
所有剩餘單詞都被分配給最後一個變數
read -p “Enter a filename:“ FILE


bash如何展開命令列

把命令列分成單個命令詞
展開別名
展開大括號的宣告({})
展開波浪符宣告(~)
命令替換$()和``)
再次把命令列分成命令詞
展開檔案通配(*、?、[abc]等等)
準備I/0重導向(<、>)
執行命令
防止擴充套件
反斜線(\)會使隨後的字元按原意解釋

$echoYourcost:$5.00

Yourcost:$5.00
加引號來防止擴充套件
單引號(’)防止所有擴充套件
$(美元符號)-變數擴充套件
`(反引號)-命令替換
\(反斜線)-禁止單個字元擴充套件
!(歎號)-歷史命令替換


Profile類

按功能劃分,存在兩類:
profile類和bashrc類
profile類:為互動式登入的shell提供配置
全域性:/etc/profile, /etc/profile.d/*.sh
個人:~/.bash_profile
功用:
(1) 用於定義環境變數
(2) 執行命令或指令碼
Bashrc類
bashrc類:為非互動式和互動式登入的shell提供配置
全域性:/etc/bashrc
個人:~/.bashrc
功用:
(1) 定義命令別名和函式
(2) 定義本地變數


locate命令

locate KEYWORD
有用的選項

-i不區分大小寫的搜尋
-n N只列舉前N個匹配專案
-r 使用正則表示式
示例
搜尋名稱或路徑中帶有“conf”的檔案
locate conf
使用Regex來搜尋以“.conf”結尾的檔案
locate -r ‘.conf$’

find******************************練習

查詢條件
指搜尋層級
-maxdepthlevel 最大搜索目錄深度,指定目錄為第1級
-mindepthlevel 最小搜尋目錄深度
先處理目錄內的檔案,再處理目錄
-depth


根據檔名和inode查詢:

-name “檔名稱”:支援使用glob
*, ?, [], [^]
-iname"檔名稱":不區分字母大小寫
-inumn 按inode號查詢
-samefilename 相同inode號的檔案
-links n 連結數為n的檔案
-regex“PATTERN”:以PATTERN匹配整個檔案路徑,而非檔名稱


根據屬主、屬組查詢:

-user USERNAME:查詢屬主為指定使用者(UID)的檔案
-group GRPNAME: 查詢屬組為指定組(GID)的檔案
-uidUserID:查詢屬主為指定的UID號的檔案
-gidGroupID:查詢屬組為指定的GID號的檔案
-nouser:查詢沒有屬主的檔案
-nogroup:查詢沒有屬組的檔案


根據檔案型別查詢:

-type TYPE:
•f: 普通檔案
•d: 目錄檔案
•l: 符號連結檔案
•s:套接字檔案
•b: 塊裝置檔案
•c: 字元裝置檔案
•p: 管道檔案
空檔案或目錄
-empty
find /app -type d -empty

find示例

備份配置檔案,新增.orig這個副檔名

find -name “*.conf” -exec cp {} {}.orig\;  

提示刪除存在時間超過3天以上的joe的臨時檔案

find/tmp-ctime+3-userjoe-okrm{}\;  

在主目錄中尋找可被其它使用者寫入的檔案

find ~-perm-002 -execchmodo-w{}\;   
find /home –type d -ls  

locate text.sh搜尋檔案
因為是從locate的資料庫搜尋檔案的,速度快不影響伺服器效能,適合搜尋本來就在記憶體中的檔案,而新建的檔案不會馬上搜索到,可以輸入updatedb更新locate資料庫
locata +"*萬用字元"搜尋檔案
locata -r ".sh$"搜尋以.sh結尾的檔案(支援正則表示式)
**find搜尋是實時搜尋,在硬碟上搜索,速度慢且影響伺服器效能,而且沒有許可權的資料夾搜尋不進去 ***********************(面試常有)
find (路徑) -name(iname) "text"搜尋包含text的檔案+i後忽略大小寫

例子

find -name "*.txt"  查詢以txt結尾的檔案  
find -empty 搜尋空檔案或者空目錄  
find / -size 10k 搜尋9-10k的檔案  
find / -size -10k  搜尋0-10k的檔案  
find / -size +10k  搜尋大於10k的檔案  
find / -size +5k -size 10k 搜尋5-10K的檔案  
find -name "*.txt" -exec(批量) rm {} \; 查詢字尾名為txt的檔案並 批量 刪除  

chmod a+x 檔案 給所有人加上此檔案的執行許可權
ll -d 查詢當前目錄下的許可權

處理文字的工具sed ********重點

sed工具
用法:

sed [option]... 'script' inputfile...  
常用選項:  
-n不輸出模式空間內容到螢幕,即不自動列印  
-e多點編輯  
-f /PATH/SCRIPT_FILE從指定檔案中讀取編輯指令碼  
-r支援使用擴充套件正則表示式  
-i.bak備份檔案並原處編輯  

script:
‘地址命令’
地址定界:
(1) 不給地址:對全文進行處理
(2) 單地址:
.#: 指定的行,$:最後一行
/pattern/:被此處模式所能夠匹配到的每一行
(3) 地址範圍:
.#,#
.#,+#
/pat1/,/pat2/
.#,/pat1/
(4) ~:步進

編輯命令:

d刪除模式空間匹配的行,並立即啟用下一輪迴圈
p列印當前模式空間內容,追加到預設輸出之後
a[\]text在指定行後面追加文字,支援使用\n實現多行追加
i[\]text在行前面插入文字
c[\]text替換行為單行或多行文字
w /path/file儲存模式匹配的行至指定檔案
r /path/file讀取指定檔案的文字至模式空間中匹配到的行後
=為模式空間中的行列印行號
!模式空間中匹配行取反處理

SED筆記*******************練習

SED

用法: 不加-i時僅僅是列印到螢幕顯示,加-i可以修改檔案,一般加-i.bak備份一個.bak檔案

sed[option]... 'script' inputfile...  
常用選項:  
-n不輸出模式空間內容到螢幕,即不自動列印  
-e多點編輯  
-f /PATH/SCRIPT_FILE從指定檔案中讀取編輯指令碼  
-r支援使用擴充套件正則表示式  
-i.bak備份檔案並原處編輯  
編輯命令:  
d刪除模式空間匹配的行,並立即啟用下一輪迴圈  
p列印當前模式空間內容,追加到預設輸出之後  
a` [\]`text在指定行後面追加文字,支援使用\n實現多行追加  
`i[\]`text在行前面插入文字  
`c [\]`text替換行為單行或多行文字  
w /path/file儲存模式匹配的行至指定檔案  
r /path/file讀取指定檔案的文字至模式空間中匹配到的行後  
=為模式空間中的行列印行號  
!模式空間中匹配行取反處理  

例子

sed ‘2p’ /etc/passwd  
sed –n ‘2p’ /etc/passwd  顯示第2行  
sed –n ‘1,4p’ /etc/passwd  顯示1-4行  
sed –n ‘/root/p’ /etc/passwd  顯示帶有root的行  
sed –n ‘2,/root/p’ /etc/passwd  從2行開始  
sed -n ‘/^`$`/=file 顯示空行行號  =代表行號   
sed –n –e ‘/^$/p’ –e ‘/^$/=file  
sed –n –r '/^#|^$/d' + file 刪除該檔案中帶#註釋和空白的行  
sed ‘/root/a\superman’ /etc/passwd行後  
sed ‘/root/i\superman’ /etc/passwd行前  
sed ‘/root/c\superman’ /etc/passwd代替行  
s///查詢替換,支援使用其它分隔符,[email protected]@@,s###  

替換標記:
g行內全域性替換
p顯示替換成功的行
w /PATH/FILE將替換成功的行儲存至檔案中
nl 可以顯示行號


例項

sed -n '/^u/p'  /data/f1  打印出data下的f1檔案中以u開頭的行  
sed -n '3,9'只顯示3-9行  
sed -n '/^ftp/,/^lib/' passwd 顯示passwd檔案中以ftp開頭和以lib開頭之間的行  
sed -n '1~2p' 列印奇數行  
sed -n '2~2p' 列印偶數行  
sed -i '/^SELINUX=/cSELINUX=disabled' /etc/selinux/config  把config檔案中的SELINUX=enforcing改為SELINUX=disabled  禁用selinux   
sed -n 's/tmpfs/tempfilesystem/g' /etc/fstab 將檔案fstab中的tmpfs替換為  tempfilesystem,並且只顯示替換結果,s為查詢替換,p為只顯示替換的那一行  
sed -r 's/[[:alpha:]]/\u&/g' +檔案 [[:alpha:]]意思為字母,u為大寫,&表示搜尋到的內容,用u&替換原內容,把所有的字母替換為大寫  
sed -r 's/[[:alpha:]]/\l&/g' +檔案 [[:alpha:]]意思為字母,l為小寫,&表示搜尋到的內容,用u&替換原內容,把所有的字母替換為小寫  
sed -r 's/^[^#]/#&' +檔案 將檔案中不是#開頭的行加上#並顯示,其中&代表被搜尋出來的內容,等於用#&替換了原來的內容,加-i可以直接修改 .............................(重點)  
sed -nr '/.*CMDLINE_LINUX.*/s#(.*)"#\1 net.ifnames=0"#p' /etc/default/grub   在帶有CMDLINE_LINUX的一行後加上net.ifnames=0  僅在7系統需要修改    ......................修改  
s///查詢替換,支援使用其它分隔符,[email protected]@@,s###  

替換標記:
g行內全域性替換
p顯示替換成功的行
w /PATH/FILE將替換成功的行儲存至檔案中