第一節:基礎
ls -lh ——可以用戶友好的方式看到文件大小
file 文件名 ——查看文件類型
stat 文件名 ——查看文件當前狀態
man 命令/函數名 ——查看詳細的幫助文檔
man中看某一命令選項的定位技巧 —— 輸入/ -n -n前面要有一定的空格
#!/bin/bash
echo “Hello World!”
chmod 777 hello.sh或chmod a+x hello.sh等
./hello.sh執行
echo -e選項用來增強,支持轉義字符。
var=world
echo “hello $var \n” ——輸出hello world \n
echo -e “hello $var \n” ——輸出hello world后有換行
echo -e "\033[32;40mHELLO YOU \033[0m"
——輸出不同顏色的字體,以\033[開頭,
——\033[0m結尾,3x是前景色,4x是背景色
第二節:變量
set/declare ——查看環境變量
env ——查看環境變量
兩者是有區別的,set/declare顯示所有的本地變量,env是獲取環境變量
unset 變量名 ——取消變量
shell中所有變量都是字符串,變量區分大小寫,如foo和Foo是不同的變量;
變量必須以字母或下划線開頭;
變量名和值之間沒有空格:MSG=Hello √ MSG= Hello×
只讀變量用readonly: readonly MSG=12 MSG=13×
變量引用:echo $var / echo ${var} 后者更加嚴格
修改環境變量:PATH=$PATH:/bin/opt
永久修改環境變量:vim ~/.bashrc;export PATH=${PATH}:/bin/opt ;source .bashrc
補充:
/etc/profile:
此文件為系統的每個用戶設置環境信息,當用戶第一次登錄時,該文件被執行.
並從/etc/profile.d目錄的配置文件中搜集shell的設置.
/etc/bashrc:
為每一個運行bash shell的用戶執行此文件.當bash shell被打開時,該文件被讀取.
~/.bash_profile:
每個用戶都可使用該文件輸入專用於自己使用的shell信息,當用戶登錄時,該
文件僅僅執行一次!默認情況下,他設置一些環境變量,執行用戶的.bashrc文件.
~/.bashrc:
該文件包含專用於你的bash shell的bash信息,當登錄時以及每次打開新的shell時,該
該文件被讀取.
~/.bash_logout:
當每次退出系統(退出bash shell)時,執行該文件.
另外,/etc/profile中設定的變量(全局)的可以作用於任何用戶,而~/.bashrc等中設定的變量(局部)只能繼承/etc/profile中的變量,他們是"父子"關系.
注意他們之間有執行的優先級;
第三節:重定向
輸出重定向
ls -l > dat.txt ——重定向到文件,會創建新文件
ls -l >> dat.txt ——追加到文件末尾
ls -l > /dev/null ——空洞文件
ls xxx > txt ——文件不存在,則無法重定位,會輸出錯誤信息
ls xxx > txt 2>&1 ——成功,1代表標准輸出,2>&1表示2等同於1
輸入重定向
cat >> dat.txt <<R ——表示以R結束!(輸入想要的數據后輸入R結束)
read var <dat.txt ——將dat.txt中的第一行作為值付給變量var
管道
du -ah | sort -n ——列出一個目錄的所有文件,按文件大小排序
ps aux | grep MySQL ——查看服務
rpm -qa | grep vsftpd ——查看軟件是否已經安裝可以使用這個方法
第四節:數學運算
(expr () let)
expr 1 + 2 ——注意要有空格 expr格式要求較高
var=$(expr 1 \* 8) ——*要用轉義
TMP=$((1+2)) ——直接使用() 不用空格
let var=3*8
echo $var
計划任務crontab -e進入編輯
第五節:引用
1.雙引號:使用雙引號可以輸出除$、`、\ 以外的任意字符
echo “$hello world” ——輸出 world
2.單引號:使用單引號會忽略任何的引用值
hello=10 echo ‘$hello’——輸出$hello
3.反引號:用於將系統命令輸出到變量
echo `ls` ——相當於執行ls命令
echo “`ls` Hello world” ——執行ls命令后繼續打印hello world
4.反斜線:防止shell誤解特殊含義的字符
如& * + | ? $等等
第六節:grep和正則表達式
1.grep常用 grep -n(顯示行號) -r(遞歸) -v(取反) --color --include等選項。
grep -nr “Hello” /home /var --include=*.c
2.正則表達式
元字符:[ ] \ ^ $ . ? | * + ( )
^ ——匹配行首 ls | grep ^[0-9]以0-9開頭的; ls |grep ^[^A]以非A開頭的
$ ——匹配行尾 ls | grep c$以c結尾的, 還可以使用’ ’ ls |grep ‘^[m]c$’
* ——匹配0次或多次
? ——匹配0次或1次
. ——匹配任意單字符
partten\{n\} ——匹配前面partten出現次數 n為次數
grep --color '^[0-9]\{3\}' txt
partten\{n,\} ——匹配前面partten出現次數 n為至少出現次數
grep --color '^[0-9]\{1,\}' txt
partten\{n,m\} ——匹配前面partten出現次數 出現次數為n-m之間
grep --color '^[0-9]\{1,3\}' txt
3.匹配開頭和結尾字符
grep ‘^[hello]’ txt ——以hello開頭,或grep ‘^hello’ txt
grep ‘hello$’ txt ——以hello結尾的單詞
grep ‘^\bHello\b’ txt ——匹配整個單詞Hello
第七節:sed命令
-n -p選項
sed ‘p’ filename ——查看文件內容 p代表print 注意:會顯示兩行
sed -n ‘p’ filename ——加上-n 表示只輸出模式空間的內容
sed -n ‘1 p’ filename ——只打印第一行 2 p打印前兩行
sed -n ‘1,3 p’ filename ——打印1-3行
sed -n ‘/main/ p’ file ——打印含有main的行
sed -n ‘/^main/ p’ file ——打印以main開頭的行
sed -n ‘/main$/ p’ file ——打印以main結尾的行
sed -n ‘/^[0-9]/\{3\} p’ file——以數字開頭 並出現三次
-d選項(delete),與p用法類似:
sed ‘1,3 d’ file ——刪除1-3行
-f選項:從文件中讀入命令 建立文件cmd.sed 如內容:/main/ p
sed -f cmd.sed filename
-e選項:后面可以接多個命令
sed -n ‘/main/ p’ -e ‘/hello/ p’ filename
-i重要!
-i選項,會直接操作到文件內容
-s替換:
sed ‘1 s/main/hello/’ filename ——把第一行中main換成hello
sed ‘/main/ s/he/llo/’ filename ——把main所在字符串所在中he換成llo
sed ‘2 /main/ s/he/llo/’ filename ——把第二行且含有main的行中he換成llo
如果沒有address-range和partten-range,就會操作到所有行,如
sed ‘s/main/hello/’ filename ——把所有行中的main換成hello
substitute-flags:
g(global):全局開關 sed ‘s/main/hello/g’ filename
數字:把每一行第n個符合條件的替換 sed ‘s/main/hello/2’ filename
第二個出現的main
p:打印,不多說
w(write):輸出到文件 sed ‘ s/main/hello/w out.txt’ filename
i(ignore):忽略大小寫
各種標記可以聯合使用:
sed ‘s/main/fuck/gipw 2.txt’ filename
&:
sed ‘s/main/[&]/’ filename 把每一行main換為[main]
實例:ll > txt
txt中內容如下:
總用量 32
drwxrwxr-x. 7 xxx xxx 4096 10月 18 20:19 install
-rw-rw-r--. 1 xxx xxx 0 12月 18 21:12 txt
drwxr-xr-x. 9 xxx xxx 4096 9月 5 17:22 vim
drwxrwxr-x. 9 xxx xxx 4096 12月 15 21:48 work
我只想要得到txt那一行的21:12
怎么做?
答案:
cat txt | grep txt | sed 's/.*..:...*/\1/g'
又如echo "hello my world" | sed 's/.*my.*/[\1]/'這樣輸出:[my]
第八節.AWK命令
awk命令
比較好的參考資料:
http://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html
格式1:awk -Fs ‘BEGIN{ } / parten/ {action} END{ }’
action中的內容會循環執行 begin與end的內容只會執行一次
awk -F, ‘print $1,$2,$3’ txt ——按逗號分隔成每一個段 打印每一個段
加逗號會輸出空格 以方便我們觀察
awk -F, ‘print $1 $2 $3’ txt ——這樣的會打印出來的沒有逗號分隔
也可以不加逗號,加| 、 制表符等等,如下:
awk -F, ‘print $1”|”$2”|”$3’ txt
awk -F, ‘print $1”\t”$2 “\t”$3’ txt
awk -F, ‘/main/ print $1,$2,$3’ txt——匹配含有main的行
awk -F. '/txt/ {print $1 "\t" $2}' txt——以.作為分隔符。。。
內置變量:
FS內置變量 代表分隔符 OFS代表輸出分隔符
awk 'BEGIN{FS=","; OFS="\t"; printf("===================\n")} {print $1,$2, $3} END{print("===================")}' txt
可以指定多個分隔符,如 . : %三個
awk 'BEGIN{FS=[.:%]; OFS="\t"; printf("===================\n")} {print $1,$2, $3} END{print("===================")}' txt
指定分隔符並換行RS
文件內容:
101
lvy
BOSS
-
102
XXX
XXX
-
103
QQQ
QQQ
-
要求得到格式如:
lvy:BOSS
XXX:XXX
QQQ:QQQ
答案:
awk 'BEGIN{FS="\n"; OFS=":"; RS="-\n"} {print $2,$3} END{}' txt
輸出分隔符ORS
awk 'BEGIN{FS="\n"; OFS=":"; RS="-\n"; ORS="\n----------\n"} {print $2,$3} END{}' txt
用在在每一行執行完畢后輸出一些內容。。。
lvy:BOSS
----------
XXX:XXX
----------
QQQ:QQQ
----------
awk中print與printf
print中不需要對變量進行處理,如果是字符串 加雙引號
printf與C語言中的用法是一樣的。
復習AWK:
awk '{print $0}' txt ——打印txt中所有行
awk 'BEGIN{OFS=":";RS="-\n"} {print $2,$3}' txt
默認的域分隔符是空格 域分隔符使用-F指定
sudo cat /etc/passwd | awk -F: '{print $1}' ——冒號作為域分隔符
對比sudo cat /etc/passwd | awk '{print $1}'看看
統計/etc/passwd:文件名,每行的行號,每行的列數,對應的完整行內容:
awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
awk 'BEGIN{print("Hello"); FS=".";} {print FILENAME, NR, $2} END{print("World!")}' txt
FILENAME代表文件名;NR代表行號;NF代表列數 $NF可以取最后列
自定義變量:
必須以字符開始,不能使用內置變量,最好放在begin段中
awk -f xxx.awk file —— -f選項指定可以在后面接一個awk腳本。
必須是下面這種形式 BEGIN{要放在一行
BEGIN{
total=0;
}
{
total += 1;
}
END{
print “total is :”, total;
}
一元運算符:+返回數字本身 - 改變數字的符號 ++遞增操作
算術運算符:+ - * /
字符串連接:str = str1”__”str2; 可以連接
比較/邏輯運算符:> >= < <= && || 等
正則表達式:~匹配 !~不匹配
實例:統計/etc/passwd下有多少用戶使用/bin/bash
cat /etc/passwd | awk -F: 'BEGIN{NUM=0;} /\/bin\/bash/ {print $NF; NUM++;} END{print "The number who use /bin/bash is:", NUM}'
AWK條件與循環:
與c語言一樣,awk中也有條件、循環語句
例子:awk -F, ‘{if ($3 == 500) print $1; else print “Not Found!”;}’ /etc/passwd
第九節.shell環境
變量別名:shell中輸入alias ll=”ls -l”
如果想退出終端后還有效的話 就寫入~/.bashrc
stty -echo ——設置輸出不回顯 可以再輸入密碼時,設置。
stty echo ——回顯
cal ——查看日歷
cal [[day][month]year] [代表是可選的] cal 7 2014表示查看2014年7月份
data ——查看時間
date “+%A” 查看星期幾
date "+%Y-%m-%d %H:%M:%S" ——顯示2014-12-26 21:06:29
find命令補充:find [option] [-exec | -ok] command {} \;
-exec、-ok選項 -exec是不安全的,-ok是安全的
find /home -name test.txt -exec rm {} \; ——找到后會立刻刪除,不會提示
find . -name aaa -ok rm {} \; ——會提示是否刪除
find . -name aaa -exec cp {} /home \;
-xargs選項
find . -name aaa | xargs rm
find . -name aaa | xargs -i mv {} /opt
實例:查找當前目錄下非.c的文件 並進行刪除:
find . -type f ! -name *.c | xargs rm -f ——注意感嘆號的位置
第十節.shell腳本編程
shell條件語句:
if list then
do something here
elif list then
do another thing here
else
do something else here
fi
EX1:
#!/bin/sh
SYSTEM=`uname -s` #獲取操作系統類型
if [ $SYSTEM = "Linux" ] ; then #如果是linux的話打印linux字符串 注意[]中兩邊的空格
echo "Linux"
elif [ $SYSTEM = "FreeBSD" ] ; then
echo "FreeBSD"
elif [ $SYSTEM = "Solaris" ] ; then
echo "Solaris"
else
echo "What?"
fi #ifend
基本上和其他腳本語言一樣。沒有太大區別。不過值得注意的是。[]里面的條件判斷。
1 字符串判斷
str1 = str2 當兩個串有相同內容、長度時為真
str1 != str2 當串str1和str2不等時為真
-n str1 當串的長度大於0時為真(串非空)
-z str1 當串的長度為0時為真(空串)
str1 當串str1為非空時為真
2 數字的判斷
int1 -eq int2 兩數相等為真
int1 -ne int2 兩數不等為真
int1 -gt int2 int1大於int2為真
int1 -ge int2 int1大於等於int2為真
int1 -lt int2 int1小於int2為真
int1 -le int2 int1小於等於int2為真
3 文件的判斷
-r file 用戶可讀為真
-w file 用戶可寫為真
-x file 用戶可執行為真
-f file 文件為正規文件為真
-d file 文件為目錄為真
-c file 文件為字符特殊文件為真
-b file 文件為塊特殊文件為真
-s file 文件大小非0時為真
-t file 當文件描述符(默認為1)指定的設備為終端時為真
3 復雜邏輯判斷
-a 與
-o 或
! 非
一些預定義的變量:
linux中shell變量$#,$@,$0,$1,$2的含義解釋:
$$ Shell本身的PID(ProcessID)
$! Shell最后運行的后台Process的PID
$? 最后運行的命令的結束代碼(返回值)
$- 使用Set命令設定的Flag一覽
$* 所有參數列表。如"$*"用「"」括起來的情況、以"$1 $2 … $n"的形式輸出所有參數。
$@ 所有參數列表。如"$@"用「"」括起來的情況、以"$1" "$2" … "$n" 的形式輸出所有參數。
$# 添加到Shell的參數個數
$0 Shell本身的文件名
$1~$n 添加到Shell的各參數值。$1是第1參數、$2是第2參數…。
補充:
filename1 -nt filename2 如果 filename1 比 filename2 新,則為真 [ /tmp/install/etc/services -nt /etc/services ]
filename1 -ot filename2 如果 filename1 比 filename2 舊,則為真 [ /boot/Image -ot arch/i386/boot/bzImage ]
轉自:http://blog.csdn.net/scottly1/article/details/42197997
