工作兩年后,發現sheel腳本用的挺多,一直感覺自己用的還可以,后來才發現很多地方自己不夠清楚,特寫下這篇博客對用到的地方進行總結。
一、sheel加載的四種方式。
1、工作目錄執行。
工作目錄執行,指的是執行腳本時,先進入到腳本所在的目錄(此時,稱為工作目錄),然后使用 ./腳本方式執行 [tan@tan scripts]$ ./test.sh -bash: ./test.sh: Permission denied [tan@tan scripts]$ chmod 764 test.sh [tan@tan scripts]$ ./test.sh Hello Shell 如圖,報了權限錯誤,上一篇博文有提到,這里需要賦權,使用chmod 764 test.sh 賦權后就可以正常執行了 ./的意思是說在當前的工作目錄下執行hello.sh。如果不加上./,bash可能會響應找到不到hello.sh的錯誤信息。
因為目前的工作目錄 (/data/shell)可能不在執行程序默認的搜索路徑之列,也就是說,不在環境變量PASH的內容之中。
查看PATH的內容可用 echo $PASH 命令。現在的/data/shell就不在環境變量PASH中的,所以必須加上./才可執行。
2、絕對目錄執行。
絕對目錄和工作目錄執行沒有本質的差別,都需要有可執行權限。
3、sh執行。
指的是用腳步對應的sh或bash來解析腳步執行。
[tan@tan scripts]$ sh test.sh Hello Shell [tan@tan scripts]$ bash test.sh Hello Shell 注意,若是以方法三的方式來執行,那么,可以不必事先設定shell的執行權限,甚至都不用寫shell文件中的第一行(指定bash路徑)。
因為方法三 是將hello.sh作為參數傳給sh(bash)命令來執行的。這時不是hello.sh自己來執行,而是被人家調用執行,所以不要執
行權限。那么不用 指定bash路徑自然也好理解了啊,呵呵……。
4、source和.執行。
指的是在當前的shell環境中執行,也需要有執行權限,但是相比前面三個不會創建一個子進程來執行。
[tan@tan scripts]$ . test.sh Hello Shell [tan@tan scripts]$ source test.sh Hello Shell
變量的傳遞總結如下鏈接:https://zhuanlan.zhihu.com/p/60761450
二、dirname和basename的使用
cur_dir=$(cd $(dirname $0);pwd) #獲取當前路徑 BASE_PARENT_DIR=$(dirname $cur_dir)#獲取目錄的上一級目錄
basename /usr/bin/sort Output "sort". basename include/stdio.h .h Output "stdio".
三、echo
echo <和echo <<的作用
echo > 是輸出重定向 echo >> 輸出追加重定向
> /dev/null 2>&1 1和2都輸出到黑洞
echo 的顯示
-n do not output the trailing newline -e enable interpretation of backslash escapes -E disable interpretation of backslash escapes (default)
https://blog.csdn.net/xnn_1993/article/details/87090754
四、sed
sed表示Stream Editor,流式編輯器又名行編輯器,每次編輯一行,它可以執行各種功能,如搜索、查找、修改、插入或刪除文件,此外,他也可以
執行復制的正則表達式匹配。它可以用於以下目的:
- 查找和替換匹配給定的格式的內容
- 在指定行查找和替換匹配給定格式的內容
- 在所有行查找和替換匹配給定格式的內容
- 搜索並同時替換兩種不同的模式
使用的格式如下:sed [操作選項] ‘命令’ 文件名,
常用的操作選項如下:
-n:指定處理后只顯示該行 -e:進行多項編輯任務 -i:直接修改讀取的文件內容,而不是由屏幕輸出。
-f 該選項會將其后文件中的腳步命令添加到已有的命令中。
常用的命令選項如下:
p:打印匹配行
a:新增
c:替代一行
d:刪除定位行
s:替代一行中的某些部分
g:全局替換標志
n:1-512之間的數字,表示出現第幾次替換。
正則表達式:
1、符號".": 匹配任意一個字符,除了換行符,但是需要注意的是,在sed中不能匹配換行符,但是在awk中可以匹配換行符。類似shell通配符中的"?",匹配一個任意字符。 2、符號"*": "*"表示前邊字符有0個或多個。".*"表示任意一個字符有0個或多個,也就是能匹配任意的字符。類似shell通配符中的"*",可以匹配任意字符。 3、 符號"[]": "[ ]"中括號中可以包含表示字符集的表達式。使用方法大概有如下幾種。 [a-z]:表示a-z字符中的一個,也就是小寫字母。 [0-9]:表示0-9字符中的一個,也就是表示數字。 [A-Z]:表示大寫字母。 [a-zA-Z]:表示字符集為小寫字母或者大寫字母。 [a-zA-Z0-9]:表示普通字符,包括大小寫字母和數字。 [abc]:表示字符a或者字符b或者字符c。 [^0-9]:表示非數字類型的字符,^表示取反意思,只能放在中括號的開始處才有意義。 [-cz]:表示字符-或者字符c或者字符z,注意與[c-z]的區別,因為-符號沒有放在e和f之間。 4. 符號"^": ^"表示行首的意思,也就是每一行的開始位置。在這里並不是上邊字符范圍中取反的意思,^符號只有在"[]"符號的開頭處才能表示字符取反。 ^abc:表示以abc開頭的字符串abc。 ^abc.*:表示以abc開頭的字符串abcxxx。 5. 符號"$" "$"表示行尾的意思,也就是每一行的結尾位置,很好理解,和"^"正好相反。 world$:表示以world結尾的字符串world,如果該行中間有world字符串是不符合匹配條件的。 ^$:表示空行。行首和行尾沒有內容,可不就是空行嘛。 6. 符號"\": "\"表示是轉義字符,和其它語言中用到的轉義字符意義基本上是一樣的。其實簡單理解,就是把元字符轉義為普通字符,比如"\\"表示普通符號"\",把普通字符轉換為特殊意義符號,比如"\n"表示把普通字符n轉義為換行符。 7. 符號"{}": "{}"表示前邊字符的數量范圍,大概有三種用法,其實容易理解,看例子就知道了,但是必須注意要加上轉義字符"\",否則不生效,表示為普通字符"{"或"}"。 \{2\}:表示前邊字符的重復次數是2。 \{2,\}:表示前邊字符的重復次數至少是2,也就是大於等於2。 \{2,9\}:表示前邊字符的重復次數大於2但小於9。 8. 符號"\<"和"\>": "\<"表示匹配條件為詞首的位置,理解上可以對比 "^" 行首。 舉個例子,"nihao 1hello 2hello3 hello4"有這么內容的一行內容。 "\<hello"匹配結果"nihao 1hello 2hello3 hello4"; "hello\>"匹配結果"nihao 1hello 2hello3 hello4",這種匹配方式用的不是太多,用到會用就OK
使用例子:
1、顯示 sed -n '2p' tmp.txt 只顯示第二行 sed -n '1,3p' tmp.txt 打印第一行到第三行 sed -n '/mov/p' tmp.txt 打印含mov的行
sed -n "/kevin/,/frank/"p tmp.txt 打印匹配kevin開始,frank為結束的行
2、刪除
sed '2d' tmp.txt 刪除第二行 sed '3,$d' tmp.txt 刪除第三行到最后一行,$表示最后一行 3、查詢 sed -n '/hello/p' tmp.txt查詢包含關鍵字hello的所有行 4、代替 sed '1c Hi' tmp.txt 第一行替代為Hi
sed '/tom/c Hi' tmp.txt 僅僅替換有tom的行 sed -n '/hello/p' tmp.txt | sed 's/hello/bid/g'把hello替換bird
sed 's/to/tt/2' tmp.txt 只替換第2個to
sed 's/^/\/\/ comment /' tmp.txt開頭加點注釋
sed 's/$/\/\/ comment /' tmp.txt末尾加點注釋
sed -i /^servial/c"hello" tmp.txt 以serial開頭的行替換為hello
5、插入 sed -i '$a bye' tmp.txt 在最后一行插入bye
sed -i 3d tmp.txt 可以看到命令不一定非要用‘’
五、awk
awk是一個強大的文本分析工具,它把文件逐行的讀入,以空格為默認分割符將每行分割為多個字段。
使用方式:awk [OPTIONS] ‘pattern {action}’ filenames,其中pattern是要查找的內容(可以沒有,也叫匹配的規則),action找到匹配內容時所執行的命令
last -n 5 | awk '{print $1}' 列出最近五個登錄用戶 cat /etc/passwd | awk -F ':' '{print $1}' awk -F ':' '$1=="root" {print $0}' /etc/paswd -F指定分隔符,$0表示整行,$1表示第一列,條件后有空格
awk -F 'a|b' '{}'或者awk -F '[a|b]' '{}'以a或者b作為分割符,和awk -F "[ab]" '{}'作用一樣
awk -F "[a][b]" '{}'這種形式的分隔符是合並的關系,即以ab作為一個字符分割
awk中兩個特別的表達式,BEGIN和END,都可以用於pattern中,在程序賦予初始狀態和程序結束之后的一些掃尾工作
awk -F, ‘BEGIN{sum=0}{sum==$3}END{print sum/1024/1024" GB"}'