Linux Shell实例精讲学习笔记
第一章:shell基礎
●umask?? --查看當前用戶創建文件或文件夾時的默認權限
eg:
[test@szbirdora 1]$umask
0002
[test@szbirdora 1]$ls -lh
-rw-rw-r--???? test test? myfile???
drwxrwxr-x???test test 1
上面的例子中我們看到由test默認創建的文件myfile和文件夾1的權限分別為664,775.而通過umask查到的默認權限為0002.所以可以推斷出umask的計算算法為:
umask??????????????????? file????????????????????? directory
0??????????????????????????6????????????????????????? 7
1????????????????????????? 5????????????????????????? 6
2??????????????????????????4??????????????????????????5
3??????????????????????????3????????????????????????? 4
4????????????????????????? 2??????????????????????????3
5????????????????????????? 1????????????????????????? 2
6????????????????????????? 0????????????????????????? 1
7????????????????????????? 0????????????????????????? 0
●連接ln
硬連接 ln sourcefile targetfile????????????????? 連接后的target文件大小和source文件一樣
軟連接 ln -s sourcefile targetfile????????????? 類似于windows的快捷方式
●shell script 基本結構
#!/bin/bash?????????????????--------bash shell開頭必須部分
# description???????????????--------注釋部分(可有可無,為了閱讀方便最好加以說明)
variable name=value???????? ---------變量部分,聲明變量,賦值
control segment?????????????---------流程控制結構,如判斷、循環、順序
eg.
helloworld.sh
#!/bin/bash
# This is a helloworld shell script
printchar = "hello world"
echo $printchar
[test@szbirdora 1]$sh helloworld.sh
hello world
●shell 特性
①別名????????? alias????????????????? eg. alias ll = “ls -l”
②管道????????? a |b?????????????????? 將a命令的輸出作為b命令的輸入
eg.
ls |sort?? 將ls列舉的項排序
③命令替換?? a `b` ??????????????? 將b命令的輸出作為a命令的輸入
eg.??
ls `cat myfile` 列舉出cat myfile的輸出項
④后臺運行?? nohup command&??? 可通過jobs -l查看后臺運行的腳本
⑤重定向?????? >,<????????????????????? 可以改變程序運行的輸出來源和輸入來源
⑥變量 可以用$varname 來調用變量
⑦特殊字符
??????????????????? `用來替換命令
??????????????????? \用來使shell無法認出其后的特殊字符,使其失去特殊含義
??????????????????? ;允許一行放多個命令
??????????????????? () 創建成組的命令 ??
??????????????????? {} 創建命令塊 ??
第二章:變量和運算符
●本地變量:在用戶現在的shell生命期的腳本中使用。設置變量:various_name=value.可用set 來查看。用readonly可以使變量只讀。
●環境變量:用于當前用戶下所有用戶進程(不限于現在的shell)。
設置變量:export various_name=value。用env查看。
用readonly可以使變量只讀。
●變量替換
echo ${variable name}?????????????????? 顯示實際值到variable name
echo ${variable name:+value}???? 如果設置了variable name,則顯示其值,否則為空
echo ${variable name:?value}???? 如果未設置variable name,則顯現用戶定義錯誤信息value
echo ${variable name:-value}????? 如果未設置,則顯示其值
echo ${variable name:=value}????? 如果未設置,則設置其值,并顯示
●清除變量??????????????????????????????????? unset variable name
●位置變量
位置變量表示$0,$1,$2...$9
$0 ----腳本名字
$1 ----根據參數位置表示參數1
eg.
#! /bin/bash
#parm.sh
echo "This is script name : $0"
echo "This is parameter 1: $1"
echo "This is parameter 2: $2"
[test@szbirdora 1]$sh parm.sh a b
This is script name : parm.sh
This is parameter 1: a
This is parameter 2: b
●向系統中傳遞位置變量
#!/bin/bash
#parm.sh
find /u01/test/1 -name $1 -print
[test@szbirdora 1]$ sh parm.sh myfile
/u01/test/1/myfile
●標準變量??????????????????????????????bash默認建立了一些標準環境變量,可在/etc/profile中定義
EXINIT
HOME
IFS
LOGNAME?????????????????????????????????????? --當前登錄用戶名
MAILPATH
PATH
TERM??????????????????????????????????????????????--終端信息
TZ??????????????????????????????????????????????????--時區
PS1????????????????????????????????????????????????--登錄提示,如[test@szbirdora 1]$
[test@szbirdora 1]$ echo $PS1
[\u@\h \W]\$??????????????????????????????????? --\u -user --\h -host --\W -document
PS2??????????????????????????????????????????????? --一命令多行,換行提示,如>
PWD??????????????????????????????????????????????? --當前目錄
MAILCHECK?????????????????????????????????? --每隔多少秒檢查是否有新郵件
[test@szbirdora 1]$ echo $MAILCHECK
60
SHELL
MANPATH?????????????????????????????????????? --幫助文檔位置
TERMINFO???????????????????????????????????? --終端信息
●特殊變量
$#????????? 傳遞到腳本的參數個數
$*????????? 以一個單字符串顯示所有向腳本傳遞的參數,與位置變量不同,參數可超過9個
$$????????? 腳本運行的當前進程ID號
$!????????? 后臺運行的最后一個進程的進程ID號
$@???????? 傳遞到腳本的參數列表,并在引號中返回每個參數
$-????????? 顯示shell使用的當前選項,與set命令功能相同
$????????? 顯示最后命令的退出狀態,0表示沒有錯誤,其他表示有錯誤
eg.
#!/bin/bash
#parm
echo "this is shellname: $0"
echo "this is parm1 :??? $1"
echo "this is parm2 :??? $2"
echo "show parm number : $#"
echo "show parm list :?? $*"
echo "show process id:?? $$"
echo "show precomm stat: $?"
[test@szbirdora 1]$ sh parm.sh a b
this is shellname: parm.sh
this is parm1 :??? a
this is parm2 :??? b
show parm number : 2
show parm list :?? a b
show process id:?? 24544
show precomm stat: 0
●影響變量的命令
declare 設置或顯示變量
????? -f???? 只顯示函數名
?????? -r??? 創建只讀變量
????? -x???? 創建轉出變量
?????? -i??? 創建整數變量
使用+替代-,可以顛倒選項的含義
export
????? -p?? 顯示全部全局變量
shift[n]??? 移動位置變量,調整位置變量,使$3賦予$2,使$2賦予$1???? n 前移n
typeset???? 和declare同義
注意:雙引號不能解析$,\,`三個字符,所以在雙引號中可以引用變量、轉義字符、替換變量
單引號可以解析,所以單引號中引用變量等無效
[test@szbirdora 1]$ echo "$test"
test
[test@szbirdora 1]$ echo '$test'
$test
●運算符類型
⒈按位運算符
~??? 取反
<<?? 左移運算符
>>?? 右移運算符
&??? 與
|???? 或
^???? 異或
$[ ]??? 表示形式告訴shell對方括號中表達式求值 $[a+b]
2.邏輯運算符
&&
||
>,<,=,!=
3.賦值運算符
let variablename1 +=variablename1+ varablename2
第三章 shell的輸入和輸出
1.echo??? echo [option] string
??????????? -e 解析轉移字符
?????????? -n 回車不換行,linux系統默認回車換行
轉移字符 \c \t \f \n
#!/bin/bash
#echo
echo -e "this echo's 3 newlne\n\n\n"
echo "OK"
echo
echo "this is echo's 3 ewline\n\n\n"
echo "this log file have all been done">mylogfile.txt
[test@szbirdora ~]$ sh echod.sh
this echo's 3 newlne
OK
this is echo's 3 ewline\n\n\n
上面可以看到有-e則可以解析轉移字符,沒有不能解析。echo空輸出為空
2.read 可以從鍵盤或文件的某一行文本中讀入信息,并將其賦給一個變量
read variable1 variable2
eg.
#!/bin/bash
#readname
echo -n "first name:"
read firstname
echo -n "last name:"
read lastname
echo "this name is $firstname $lastname"
3.cat??????? 顯示文件的內容,創建內容,還可以顯示控制字符
cat [options]filename1 filename2
?????????????????? -v?? 顯示控制字符(Windows文件)
???????????? cat命令不會分頁顯示,要分頁可以采用more、less
4.管道|
5.tee?????把輸出的一個副本輸送到標準輸出,另一個副本拷貝到相應的文件中,一般與管道合用
????????????? tee [options] files
????????????? -a 在文件中追加
eg.
[test@szbirdora 1]$ echo |tee myfile
[test@szbirdora 1]$ cat myfile
將myfile文件置空
6.文件重定向
command>filename??????????????????????????????????????? ---覆蓋輸出
command>>filename????????????????????????????????????? ---追加輸出
command>filename>&1???????????????????????????????? ---把標準輸出和標準錯誤重定向
command<<delimiter???????????????????????????????????? ---輸入直到delimiter分解符
command<filename???????????????????????????????????????----輸入文件內容到命令
command<-???????????????????????????????????????????????????? --- 關閉標準輸入
>nullfile.txt?????????????????????????????????????????????????????? ---創建字節為0的文件
command1<filename>command3?????????????? ---按從左到右順序執行
eg.
說明:myfile為空間
[test@szbirdora 1]$ df -lh>myfile
[test@szbirdora 1]$ cat myfile
Filesystem??????????? Size Used Avail Use% Mounted on
/dev/sda1????????????? 20G 3.3G?? 16G 18% /
none????????????????? 2.0G???? 0 2.0G?? 0% /dev/shm
/dev/sda2????????????? 79G?? 17G?? 59G 23% /u01
/dev/sda4????????????? 28G 3.9G?? 22G 15% /u02
[test@szbirdora 1]$ df -lh>myfile
[test@szbirdora 1]$ cat myfile
Filesystem??????????? Size Used Avail Use% Mounted on
/dev/sda1????????????? 20G 3.3G?? 16G 18% /
none????????????????? 2.0G???? 0 2.0G?? 0% /dev/shm
/dev/sda2????????????? 79G?? 17G?? 59G 23% /u01
/dev/sda4????????????? 28G 3.9G?? 22G 15% /u02
[test@szbirdora 1]$ df -lh>>myfile
[test@szbirdora 1]$ cat myfile
Filesystem??????????? Size Used Avail Use% Mounted on
/dev/sda1????????????? 20G 3.3G?? 16G 18% /
none????????????????? 2.0G???? 0 2.0G?? 0% /dev/shm
/dev/sda2????????????? 79G?? 17G?? 59G 23% /u01
/dev/sda4????????????? 28G 3.9G?? 22G 15% /u02
Filesystem??????????? Size Used Avail Use% Mounted on
/dev/sda1????????????? 20G 3.3G?? 16G 18% /
none????????????????? 2.0G???? 0 2.0G?? 0% /dev/shm
/dev/sda2????????????? 79G?? 17G?? 59G 23% /u01
/dev/sda4????????????? 28G 3.9G?? 22G 15% /u02
[test@szbirdora 1]$ cat >>myfile<<exit
> China
> Hubei
> Suizhou
> exit
[test@szbirdora 1]$ cat myfile
China
Hubei
Suizhou
7.exec??????? 可以用來替代當前shell。現有任何環境變量都會清除
第四章 控制流結構
1.if語句
if 條件1
then
命令1
elif 條件2
then
命令2
else
命令3
fi
------------------
if 條件
then 命令
fi
eg:
#!/bin/bash
#if test
#this is a comment line
if [ "10" -lt "12" ];then
#yes 10 is less than 12
echo "yes,10 is less than 12"
else
echo "no"
fi
注意:if語句必須以fi終止
?? "10" 前一個空格,“12”后也有一個空格。這個條件都是通過test命令來指定。條件表達為test expression或者[expression]
條件表達式中的比較函數
man test
NAME
?????? test - check file types and compare values
SYNOPSIS
?????? test EXPRESSION
?????? [ EXPRESSION ]
?????? [ OPTION
DESCRIPTION
?????? Exit with the status determined by EXPRESSION.
?????? --help display this help and exit
?????? --version
????????????? output version information and exit
?????? EXPRESSION is true or false and sets exit status. It is one of:
?????? ( EXPRESSION )
????????????? EXPRESSION is true
?????? ! EXPRESSION
????????????? EXPRESSION is false
?????? EXPRESSION1 -a EXPRESSION2
????????????? both EXPRESSION1 and EXPRESSION2 are true
?????? EXPRESSION1 -o EXPRESSION2
????????????? either EXPRESSION1 or EXPRESSION2 is true
?????? [-n] STRING
????????????? the length of STRING is nonzero
?????? -z STRING
????????????? the length of STRING is zero
?????? STRING1 = STRING2
????????????? the strings are equal
?????? STRING1 != STRING2
?????????????? the strings are not equal
?????? INTEGER1 -eq INTEGER2
????????????? INTEGER1 is equal to INTEGER2
?????? INTEGER1 -ge INTEGER2
????????????? INTEGER1 is greater than or equal to INTEGER2
?????? INTEGER1 -gt INTEGER2
????????????? INTEGER1 is greater than INTEGER2
?????? INTEGER1 -le INTEGER2
????????????? INTEGER1 is less than or equal to INTEGER2
?????? INTEGER1 -lt INTEGER2
????????????? INTEGER1 is less than INTEGER2
?????? INTEGER1 -ne INTEGER2
????????????? INTEGER1 is not equal to INTEGER2
?????? FILE1 -ef FILE2
????????????? FILE1 and FILE2 have the same device and inode numbers
?????? FILE1 -nt FILE2
????????????? FILE1 is newer (modification date) than FILE2
?????? FILE1 -ot FILE2
????????????? FILE1 is older than FILE2
?????? -b FILE
????????????? FILE exists and is block special
?????? -c FILE
????????????? FILE exists and is character special
?????? -d FILE
????????????? FILE exists and is a directory
?????? -e FILE
????????????? FILE exists
?????? -f FILE
????????????? FILE exists and is a regular file
?????? -g FILE
????????????? FILE exists and is set-group-ID
?????? -h FILE
????????????? FILE exists and is a symbolic link (same as -L)
?????? -G FILE
????????????? FILE exists and is owned by the effective group ID
?????? -k FILE
????????????? FILE exists and has its sticky bit set
?????? -L FILE
????????????? FILE exists and is a symbolic link (same as -h)
?????? -O FILE
????????????? FILE exists and is owned by the effective user ID
?????? -p FILE
????????????? FILE exists and is a named pipe
?????? -r FILE
????????????? FILE exists and is readable
?????? -s FILE
????????????? FILE exists and has a size greater than zero
?????? -S FILE
????????????? FILE exists and is a socket
?????? -t [FD]
????????????? file descriptor FD (stdout by default) is opened on a terminal
?????? -u FILE
????????????? FILE exists and its set-user-ID bit is set
?????? -w FILE
????????????? FILE exists and is writable
?????? -x FILE
???????????? FILE exists and is executable
eg.
#!/bin/bash
#if test
#this is a comment line
echo "Enter your filename:"
read myfile
if [ -e $myfile ]
then
?? if [ -s $myfile ];then
??? echo "$myfile exist and size greater than zero"
?? else
??? echo "$myfile exist but size is zero"
?? fi
else
echo "file no exist"
fi
[test@szbirdora 1]$ sh iftest.sh
Enter your filename:
11
11 exist but size is zero
2.case語句
case語句為多選擇語句。
case 值 in
模式1)
命令1
??? ;;
模式2)
命令2
??? ;;
esac
eg.
#!/bin/bash
#case select
echo -n "enter a number from 1 to 3:"
read ans
case $ans in
1)
echo "you select 1"
;;
2)
echo "you select 2"
;;
3)
echo "you select 3"
;;
*)
echo "`basename $0`:this is not between 1 and 3">&2
exit;
;;
esac
3.for 循環
for循環一般格式:
for 變量名 in 列表 (列表以空格作為分割)
do
命令1
命令2
done
eg:
#!/bin/bash
#forlist1
for loop in 1 2 3 4 5
do
echo $loop
done
4.until循環
until 條件
do
命令1
命令2
?? ...
done
條件測試發生在循環末尾,所以循環至少可以執行一次。
5.
while循環
while 命令 (可以是一個命令也可以是多個,做條件測試)
do
命令1
命令2
????? ...
done
注意:如果從文件中讀入變量<filename要放到done后
6.break和continue控制
break跳出,continue跳過
第五章 文本過濾
1.正則表達式
一種用來描述文本模式的特殊語法,由普通字符以及特殊字符(元字符)組成
^??? ----只匹配行首
$??? ----只匹配行尾
*??? ----匹配0個或多個此單字符
[]?? ----只匹配[]內字符,可以使用-表示序列范圍[1-5]
\??? ----屏蔽一個元字符的特殊含義
.??? ----匹配任意單字符
pattern\{n\} 只用來匹配前面pattern出現的次數,n為次數
pattern\{n,\}只用來匹配前面pattern出現的次數,至少為n
pattern\{n,m\}只用來匹配前面pattern出現的次數,次數在n-m之間
eg:
A\{3\}B?? AAAB
A\{3,\}B AAAB AAAAB ...
A\{3,5\}B AAAB AAAAB AAAAAB
2.find命令???? ----查找文件和目錄
find pathname -options [-print -exec -ok]
pathname --查找的目錄路徑. .--表示當前目錄,/表示根目錄
-print 輸出
-exec 對匹配的文件執行該參數所給出的shell命令,相應命令形式為'command'{} \;'??? 注意{}和\;之間的空格
-ok??? 與-exec相同,不過執行命令前會有提示
options?? :
-name
-perm
-user
-group
-mtime -n +n (atime,-ctime) 修改時間(訪問時間,創建時間)
-size n[c]
-type 查找某一類型的文件
eg.
[test@szbirdora 1]$ find ./ -mtime +5
./helloworld.sh
./nohup.out
查看./目錄(當前)下修改時間超過5天的文件
3.grep介紹
grep -c 輸出匹配行計數
grep -i 不區分大小寫
grep -h 查詢多文件時不顯示文件名
grep -H 顯示文件名
grep -l 查詢多文件時只輸出包含匹配字符的文件名
grep -n 顯示匹配行及行號
grep -s 不顯示不存在或不匹配文本的錯誤信息
grep -v 顯示不包含匹配文本的所有行(過濾文本)
eg.
[test@szbirdora 1]$ grep -n 's.a' myfile
2:/dev/sda1????????????? 20G 3.3G?? 16G 18% /
4:/dev/sda2????????????? 79G?? 18G?? 58G 23% /u01
5:/dev/sda4????????????? 28G 3.9G?? 22G 15% /u02
[test@szbirdora 1]$ grep -n '2$' myfile
5:/dev/sda4????????????? 28G 3.9G?? 22G 15% /u02
grep -options '正則表達式' filename
4.sed介紹
sed不與初始化文件打交道,它操作的只是一個拷貝,然后所有的改動如果沒有重定向到一個文件將輸出到屏幕
sed是一種重要的文本過濾工具,使用一行命令或使用管道與grep與awk相結合。
sed調用:
1.命令 sed [options] '正則表達式sedcommand' input-files
2.script :sed [options] -f sedscript input-files
sed在文本中查詢文本的方式
-行號,可以是簡單數字,或一個行號范圍
?? -使用正則表達式
x ----行號
x,y ----行號范圍從x到y
x,y! ---不包含行號x到y
sed命令選項:
-n 不打印
-c 下一個命令是編輯命令
-f 如果正在調用sed腳本文件
基本sed命令
p 打印匹配行
= 顯示文本行號
a\ 在定位行號后附加新文本信息
i\在定位行號前插入新文本信息
d 刪除定位行
c\用新文本替換定位文本
s 使用替換模式替換相應模式
r 從另一個文件中讀文本
w 寫文本到一個文件
q 第一個模式匹配完成后退去
l 顯示與八進制ascii代碼等價的控制字符
{}在定位行執行命令組
n 從一個文件中讀文本下一行,并附加在下一行
g 將模式2粘貼到/pattern n/
y 傳送字符
eg.
[test@szbirdora 1]$ sed -n '2p' myfile
c
打印myfile第2行
[test@szbirdora 1]$ sed -n '2,4p' myfile
c
f
b
打印第二行到第四行
[test@szbirdora 1]$ sed -n '/a/p' myfile
a
打印匹配a的行
[test@szbirdora 1]$ sed -n '2,/2/p' myfile
c
f
b
1
2
打印第二行到匹配'2'的行
s命令替換
[test@szbirdora 1]$ sed 's/b/a/p' myfile
a
a
a
c
d
e
替換b為a
多點編輯 -e
eg. (myfile包含a-e)
[test@szbirdora 1]$ sed -e '2d' -e 's/c/d/' myfile 11
a
d
d
e
sed命令r ---從文件中讀取選定的行,讀入輸入文件中,顯示在匹配的行后面
eg.
[test@szbirdora 1]$ cat 11
*******************Alaska***************
[test@szbirdora 1]$ sed '/a/r 11' myfile
a
*******************Alaska***************
b
c
d
e
寫入命令:w?? 將輸入文件中的匹配行寫入到指定文件中
eg.
[test@szbirdora 1]$ cat 11
b
[test@szbirdora 1]$ sed -n '/a/w 11' myfile
[test@szbirdora 1]$ cat 11
a
追加:a?? 將文本追加到匹配行的后面。sed要求在a后加\,不止一行的以\連接
eg.
[test@szbirdora 1]$ sed '/b/a\****************hello*************\-------------china---------' myfile
a
b
****************hello*************-------------china---------
c
d
e
插入命令:i?? 將文本插入到匹配行的前面。sed要求在a后加\,不止一行的以\連接
eg.
[test@szbirdora 1]$ sed '/b/i\
> THE CHARACTER B IS BEST\
> *******************************' myfile
a
THE CHARACTER B IS BEST
*******************************
b
c
d
e
下一個:n 從一個文件中讀文本下一行,并附加在下一行
退出命令 q 打印多少行后退出
eg.
[test@szbirdora 1]$ sed '3q' myfile
a alert
b best
c cook
sed script:
sed -f scriptfile myfile
5.awk介紹
awk可從文件或字符串值基于指定規則瀏覽和抽取信息
awk三種調用方式:
1.命令行方式
awk [-F field-sperator]'pattern{active}' input-files
awk [-F field-sperator]'command' input-files
awk腳本
所有awk命令插入一個文件,并使awk程序可執行,然后用awk命令解析器作為腳本的首行,以便通過鍵入腳本名稱來調用。
awk命令插入一個單獨文件
awk -f awk-script-file input-files
awk腳本由模式和動作組成
分隔符、域、記錄
注意這里的$1,$2是域與位置變量$1,$2不一樣。$0文件中的所有記錄
eg:
awk '{print $0}' myfile
awk 'BEGIN {print "IP DATE ----"}{print $1"\t"$4}END{print "end-of -report"}
[test@szbirdora 1]$ df |awk '$1!~"dev"'|grep -v Filesystem
none?????????????????? 1992400???????? 0?? 1992400?? 0% /dev/shm
[test@szbirdora 1]$ df |awk '{if ($1=="/dev/sda1") print $0}'
/dev/sda1???????????? 20641788?? 3367972 16225176 18% /
[test@szbirdora shelltest]$ cat employee
Tom Jones?????? 4424??? 5/12/66 543354
Mary Adams????? 5346??? 11/4/63 28765
Sally Chang???? 1654??? 7/22/54 650000
Billy Black???? 1683??? 9/23/44 336500
[test@szbirdora shelltest]$ awk '/[Aa]dams/' employee
Mary Adams????? 5346??? 11/4/63 28765
[test@szbirdora shelltest]$ sed -n '/[Aa]dams/p' employee
Mary Adams????? 5346??? 11/4/63 28765
[test@szbirdora shelltest]$ grep '[Aa]dams' employee
Mary Adams????? 5346??? 11/4/63 28765
三種命令方式下,使用模式匹配查詢
[test@szbirdora shelltest]$ awk '{print $1}' employee
Tom
Mary
Sally
Billy
打印文件第一列
[test@szbirdora shelltest]$ awk '/Sally/{print $1"\t"$2}' employee
Sally?? Chang
打印匹配Sally的行的第一列和第二列
[test@szbirdora shelltest]$ df |awk '$4>20884623'
Filesystem?????????? 1K-blocks????? Used Available Use% Mounted on
/dev/sda2???????????? 82567220 17488436 60884616 23% /u01
/dev/sda4???????????? 28494620?? 4589172 22457992 17% /u02
打印df輸出第四列大于××的行
格式輸出:
打印函數—
[test@szbirdora shelltest]$ date
Mon Mar 10 15:15:47 CST 2008
[test@szbirdora shelltest]$ date |awk '{print "Month:" $2"\nYear:" $6}'
Month:Mar
Year:2008
[test@szbirdora shelltest]$ awk '/Sally/{print "\t\tHave a nice day,"$1"\t"$2}' employee
??????????????? Have a nice day,Sally?? Chang
printf函數
[test@szbirdora shelltest]$ echo "LINUX"|awk '{printf "|%-10s|\n",$1}'
|LINUX???? |
[test@szbirdora shelltest]$ echo "LINUX"|awk '{printf "|%10s|\n",$1}'
|???? LINUX|
~匹配符
[test@szbirdora shelltest]$ awk '$1~/Tom/{print $1,$2}' employee
Tom Jones
awk 給表達式賦值
關系運算符:
<???????????? 小于
>???????????? 大于
==?????????? 等于
!=??????????? 不等于
>=?????????? 大于等于
<=?????????? 小于等于
~????????????? 匹配
!~??????????? 不匹配
eg.
[test@szbirdora shelltest]$ cat employee
Tom Jones?????? 4424??? 5/12/66 543354
Mary Adams????? 5346??? 11/4/63 28765
Sally Chang???? 1654??? 7/22/54 650000
Billy Black???? 1683??? 9/23/44 336500
[test@szbirdora shelltest]$ awk '$2~/Adams/' employee
Mary Adams????? 5346??? 11/4/63 28765
條件表達式:
condition?? expression1?expression2:expression3
eg.
awk '{max=($1>$2) ? $1:$2;print max}' filename
運算符
+,-,*,/,%,^,&&,||,!
[test@szbirdora shelltest]$ cat /etc/passwd |awk -F: '\
NF!=7{\
printf("line %d does not have 7 fields:%s\n",NR,$0)}\
$1!~/[A-Za-z0-9]/{printf("line %d,nonalphanumberic user id:%s\n",NR,$0)}\
$2=="*"{printf("line %d,no password:%s\n",NR,$0)}'
awk編程
遞增操作符 x++,++x
遞減操作符 x--,--x
BEGIN模塊
BEGIN模塊后面緊跟著動作塊,在讀入文件前執行。通常被用來改變內建變量的值,如:FS\RS\OFS,初始化變量的值和打印輸出標題。
[test@szbirdora shelltest]$ awk 'BEGIN{print "HELLO WORLD"}'
HELLO WORLD
[test@szbirdora shelltest]$ awk 'BEGIN{print "---------LIST---------"}{print}END{print "------END--------"}' donors
---------LIST---------
Mike Harrington:(510) 548-1278:250:100:175
Christian Dobbins:(408) 538-2358:155:90:201
Susan Dalsass:(206) 654-6279:250:60:50
Archie McNichol:(206) 548-1348:250:100:175
Jody Savage:(206) 548-1278:15:188:150
Guy Quigley:(916) 343-6410:250:100:175
Dan Savage:(406) 298-7744:450:300:275
Nancy McNeil:(206) 548-1278:250:80:75
John Goldenrod:(916) 348-4278:250:100:175
Chet Main:(510) 548-5258:50:95:135
Tom Savage:(408) 926-3456:250:168:200
Elizabeth Stachelin:(916) 440-1763:175:75:300
------END--------
重定向和管道
輸出重定向
awk輸出重定向到一個文件需要使用輸出重定向符,輸出文件名需要用雙引號括起來。
[test@szbirdora shelltest]$ awk -F: '{print $1,$2>"note"}' donors
[test@szbirdora shelltest]$ cat note
Mike Harrington (510) 548-1278
Christian Dobbins (408) 538-2358
Susan Dalsass (206) 654-6279
Archie McNichol (206) 548-1348
Jody Savage (206) 548-1278
Guy Quigley (916) 343-6410
Dan Savage (406) 298-7744
Nancy McNeil (206) 548-1278
John Goldenrod (916) 348-4278
Chet Main (510) 548-5258
Tom Savage (408) 926-3456
Elizabeth Stachelin (916) 440-1763
輸入重定向
getline函數
[test@szbirdora shelltest]$ awk 'BEGIN{"date +%Y"|getline d;print d}'
2008
[test@szbirdora shelltest]$ awk -F"[ :]" 'BEGIN{printf "What is your name?";\
getline name<"/dev/tty"}\
$1~ name{print "Found\t" name "\ton line",NR"."}\
END{print "see ya," name "."}' donors
What is your name?Jody
Found?? Jody??? on line 5.
see ya,Jody.
[test@szbirdora shelltest]$ awk 'BEGIN{while(getline<"/etc/passwd">0)lc++;print lc}'
36
從文件中輸入,如果得到一個記錄,getline函數就返回1,如果文件已經到了末尾,則返回0,如果文件名錯誤則返回-1.
管道:
awk命令打開一個管道后要打開下一個管道需要關閉前一個管道,管道符右邊可以使用“”關閉管道。在同一時間只有一個管道存在
[test@szbirdora shelltest]$ awk '{print $1,$2|"sort -r +1 -2 +0 -1"}' names
tony tram
john smith
dan savage
john oldenrod
barbara nguyen
elizabeth lone
susan goldberg
george goldberg
eliza goldberg
alice cheba
|后用""關閉管道
system函數
system("LINUX command")
system("cat" $1)
system("clear")
條件語句
1.if(){}
2.if(){}
else{}
3.if(){}
else if(){}
else if(){}
else{}
[test@szbirdora shelltest]$ awk -F: '{if ($3>250){printf "%-2s%13s\n",$1,"-----------good partman"}else{print $1}}' donors
循環語句
[test@szbirdora shelltest]$ awk -F: '{i=1;while(i<=NF){print NF,$i;i++}}' donors
循環控制語句break、continue
程序控制語句
next從輸入文件中讀取下一行,然后從頭開始執行awk腳本
{if($1~/Peter/){next}
else{print}}
exit 結束awk語句,但不會結束END模塊的處理。
數組:
awk '{name[x++]=$1;for(i=0;i<NR;i++){print i,name[i]}}' donors
(P177)---2008.3.11
awk內建函數
sub(正則表達式,替換字符[,$n]) ---域n匹配正則表達式的字符串將被替換。
[test@szbirdora shelltest]$ awk '{sub(/Tom/,"Jack",$1);print}' employee
Jack Jones 4424 5/12/66 543354
Mary Adams????? 5346??? 11/4/63 28765
Sally Chang???? 1654??? 7/22/54 650000
Billy Black???? 1683??? 9/23/44 336500
Jack He 3000 8/22/44 320000
index函數 index(字符串,子字符串) 子字符串在字符串中的位置
[test@szbirdora shelltest]$ awk 'BEGIN{a=index("hello","llo");print a}'
3
length函數 length(string) 字符串的長度
[test@szbirdora shelltest]$ awk 'BEGIN{a=length("hello world");print a}'
11
substr函數 substr(字符串,開始位置[,子字符串長度])
[test@szbirdora shelltest]$ awk 'BEGIN{a=substr("hello world",7);print a}'
world
[test@szbirdora shelltest]$ awk 'BEGIN{a=substr("hello world",7,3);print a}'
wor
match(string,正則表達式) 找出字符串中第一個匹配正則表達式的位置,其內建變量RSTART為匹配開始位置,RLENGTH為匹配開始后字符數
[test@szbirdora shelltest]$ awk '{a=match($0,/Jon/);if (a!=0){print NR,a}}' employee
1 5
[test@szbirdora shelltest]$ awk '{a=match($0,/Jon/);if (a!=0){print NR,a,RSTART,RLENGTH}}' employee
1 5 5 3
toupper和tolower函數
[test@szbirdora shelltest]$ awk 'BEGIN{a=toupper("hello");print a}'
HELLO
split函數 split(string,array,fieldseperator)
[test@szbirdora shelltest]$ awk 'BEGIN{"date"|getline d;split(d,date);print date[2]}'
Mar
時間函數
systime() ----1970年1月1日到當前忽略閏年得出的秒數。
strftime(格式描述,時間戳)
[test@szbirdora shelltest]$ awk 'BEGIN{d=strftime("%T",systime());print d}'
13:08:09
[test@szbirdora shelltest]$ awk 'BEGIN{d=strftime("%D",systime());print d}'
03/12/08
[test@szbirdora shelltest]$ awk 'BEGIN{d=strftime("%Y",systime());print d}'
2008
6.sort介紹
sort:
???? -c 測試文件是否已經排序
???? -m 合并兩個排序文件
???? -u 刪除所有復制行
???? -o 存儲sort結果的輸出文件名
???? -t 域分隔符;用非空格或tab鍵分割域
???? +n n為域號,使用此域號開始排序 (注意0是第一列)
???? -r 逆序排序
???? n 指定排序是域上的數字排序項
[test@szbirdora 1]$ df -lh|grep -v 'Filesystem'|sort +1
none????????????????? 2.0G???? 0 2.0G?? 0% /dev/shm
/dev/sda1????????????? 20G 3.3G?? 16G 18% /
/dev/sda4????????????? 28G 3.9G?? 22G 15% /u02
/dev/sda2????????????? 79G?? 17G?? 59G 23% /u01
uniq [option]files 從一個文本文件中去除或禁止重復行
???? -u 只顯示不重復行
???? -d 只顯示有重復數據行,每重復行只顯示其中一行
???? -c 打印每一重復行出現次數
???? -f n為數字,前n個域被忽略
注意要先排序
7.split cut join 分割和合并文件命令
[test@szbirdora 1]$ split -l 2 myfile split?? (每兩行分割為一個以split名稱開頭的文件)
[test@szbirdora 1]$ ls
case.sh df.out helloworld.sh iftest.sh myfile nohup.out nullfile.txt parm.sh splitaa splitab splitac splitad splitae
[test@szbirdora 1]$ cat splitaa
Filesystem??????????? Size Used Avail Use% Mounted on
/dev/sda1????????????? 20G 3.3G?? 16G 18% /
第六章 shell函數
1.定義函數
funcation name()
{
?? command1
?? ....
}
或
函數名()
?? {
?? command1
?? ...
?? }
eg.
#!/bin/bash
#hellofun
function hello()
{
echo "hello,today is `date`"
return 1
}
2.函數調用
#!/bin/bash
#hellofun
function hello()
{
echo "hello,today is `date`"
return 1
}
echo "now going to the function hello"
hello
echo "back from the function"
所以調用函數只需要在腳本中使用函數名就可以了。
3.參數傳遞
像函數傳遞參數就像在腳本中使用位置變量$1,$2...$9
4.函數文件
函數可以文件保存。在調用時使用". 函數文件名"(.+空格+函數文件名)
如:
hellofun.sh
#!/bin/bash
#hellofun
function hello()
{
echo "hello,today is `date`"
return 1
}
func.sh
#!/bin/bash
#func
. hellofun.sh
echo "now going to the function hello"
echo "Enter yourname:"
read name
hello $name
echo "back from the function"
[test@szbirdora 1]$ sh func.sh
now going to the function hello
Enter yourname:
hh
hello,hh today is Thu Mar 6 15:59:38 CST 2008
back from the function
5.檢查載入函數 set
刪除載入函數 unset 函數名
6.函數返回狀態值 return 0、return 1
7.腳本參數的傳遞
shift命令
shift n 每次將參數位置向左偏移n
#!/bin/bash
#opt2
usage()
{
echo "usage:`basename $0` filename"
}
totalline=0
if [ $# -lt 2 ];then
??? usage
fi
while [$# -ne 0]
do
??? line=`cat $1|wc -l`
??? echo "$1 : ${line}"
??? totalline=$[$totalline+$line]
??? shift?????????????????????????????? #?? $# -1
done
echo "-----"
echo "total:${totalline}"
[test@szbirdora 1]$ sh opt2.sh myfile df.out
myfile : 10
df.out : 4
-----
total:14
8.getopts命令
獲得多個命令行參數
getopts ahfvc OPTION?? --從ahfvc一個一個讀出賦值給OPTION.如果參數帶有:則把變量賦值給:前的參數--:只能放在末尾。
該命令可以做獲得命令的參數
#!/bin/bash
#optgets
ALL=false
HELP=false
FILE=false
while getopts ahf OPTION
do
?? case $OPTION in
??? a)
????? ALL=true
????? echo "ALL is $ALL"
????? ;;
??? h)
????? HELP=true
????? echo "HELP is $HELP"
????? ;;
??? f)
????? FILE=true
????? echo "FILE is $FILE"
????? ;;
??? \?)
????? echo "`basename $0` -[a h f] file"
????? ;;
??? esac
done
[test@szbirdora 1]$ sh optgets.sh -a -h -m
ALL is true
HELP is true
optgets.sh: illegal option -- m
optgets.sh -[a h f] file
getopts表達式:
while getopts p1p2p3... var ?? do
??? case var in
??? ..)
??? ....
?? esac
done
如果在參數后面還需要跟自己的參數,則需要在參數后加:
如果在參數前面加:表示不想將錯誤輸出
getopts函數自帶兩個跟蹤參數的變量:optind,optarg
optind初始值為1,在optgets處理完一次命令行參數后加1
optarg包含合法參數的值,即帶:的參數后跟的參數值
有了前面的學習,下面只記載一些在學習的過程中又忘了了一些知識點。所以記錄是零散的。
1.
shopt bash2.0以上新的命令,功能和set類似。
給變量賦值時等號兩邊不可留空格。
環境變量一般使用大寫。
2.
$# 傳遞到腳本的參數個數
$* 以一個單字符串顯示所有向腳本傳遞的參數,與位置變量不同,參數可超過9個
$$ 腳本運行的當前進程ID號
$! 后臺運行的最后一個進程的進程ID號
$@ 傳遞到腳本的參數列表,并在引號中返回每個參數
$- 顯示shell使用的當前選項,與set命令功能相同
$? 顯示最后命令的退出狀態,0表示沒有錯誤,其他表示有錯誤
3.
echo 命令中使用" "無法直接識別轉義字符,必須使用選項 -e,但可以使用$和`引用變量和命令替換。
$[] 告訴shell對方括號中表達式求值 $[a+b],如$[1+8]
4.
tee
把輸出的一個副本輸送到標準輸出,另一個副本拷貝到相應的文件中
tee -a file?????? -----a表示在文件末尾追加,不要-a則覆蓋
該命令一般與管道合用
5.
command>filename>&1 ---把標準輸出和標準錯誤重定向
command<<delimiter ---輸入直到delimiter分解符
eg:
sqlplus / as sysdba <<EOF
show parameters
exit
EOF
6.命令替換有兩種方式,老的korn風格的`linux command`和新的bash風格$(linux command)
7.定義數組
declare -a arry=(a1 a2 a3 ...)
echo ${a[n]}
8.read使用
read -a arryname???? ---讀入為數組
read -p prompt????? ----輸出提示,并把提示后的輸入存到REPLY內建變量中
[test@szbirdora 1]$ read -p "Enter your name:"
Enter your name:jack
[test@szbirdora 1]$ echo $REPLY
jack
[test@szbirdora 1]$ read -a name
jack tom susan
[test@szbirdora 1]$ echo ${name[2]}
susan
[test@szbirdora 1]$ echo ${name[0]}
jack
9.多進制整型變量表示
declare -i number
number=base#number_in_the_base
如:
declare -i number
number=2#101
number=16#A9
10.條件語句if then fi中if后的表達式可以是條件表達式(布爾表達式)或一組命令,如果是布爾表達式則表達式為真執行then后的語句,如果是命令組,則命令組狀態($?)為0執行then后面的語句。但如果是C shell則if后只能跟布爾表達式。
11.here文檔和case建立菜單:
eg.
echo "Select a terminal type:"
cat <<EOF
1) linux
2)xterm
3)sun
EOF
read choice
case $choice in
1)TERM=linux
?? export TERM
?? ;;
2)TERM=xterm
?? export TERM
;;
3)TERM=sun
?? export TERM
;;
*) echo "please select correct chioce,ths!"
;;
esac
echo "TERM is $TERM"
12.循環比較:
for variable in wordlist;do???? ---從文件或列表中給定的值循環
while command;do?????? ----當command的返回值為0時做循環
until command;do??????? ----當command的返回值不為0時作循環
select循環菜單
用 select建立菜單,需要用PS3來提示用戶輸入,輸入保存在REPLY內建變量中,REPLY的值與內建菜單關聯。在構建菜單過程中可以使用 COLUMNS和LINES兩個變量,COLUMNS決定菜單的列寬度,LINES決定可顯示的行數。select和case命令聯用可以有效的構造循環 菜單。
eg
#!/bin/bash
#Author: hijack
#Usage:Menu
t=0
j=0
d=0
PS3="Please choose one of the three boys or quit:"
select choice in Tom Jack David Quit
do
case $choice in
Tom)
t=$t+1
if (($t==5));then
echo "Tom win"
break
fi
;;
Jack)
j=$j+1
if (($j==5));then
echo "Jack win"
break
fi
;;
David)
d=$d+1
if (($d==5));then
echo "David win"
break
fi
;;
Quit) exit 0;;
*) echo "$REPLY is invalide choice" 1>&2
?? echo "Try again!"
;;
esac
done
[test@szbirdora 1]$ sh menu
1) Tom
2) Jack
3) David
4) Quit
Please choose one of the three boys or quit:1
Please choose one of the three boys or quit:2
Please choose one of the three boys or quit:1
Please choose one of the three boys or quit:1
Please choose one of the three boys or quit:1
Please choose one of the three boys or quit:1
Tom win
12.set 設置位置變量,shift移動位置變量。
set tom jack david -----$1 tom $2 jack $3 david
echo $*
tom jack david
shift 2???????????????????? -----移動兩個位置,$1,$2刪除
echo $*
david
eg:
#!/bin/bash
#Name:shift
#Author : Hijack
#Usage:shift test
#Date:080320
while (($#>0))
do
??? echo "$*"
??? shift
done
[test@szbirdora 1]$ ./shift 1 2 3 4 5 6 7
1 2 3 4 5 6 7
2 3 4 5 6 7
3 4 5 6 7
4 5 6 7
5 6 7
6 7
7
13。 break n?? ---n 代表退出第幾層循環,默認退出一層。continue n 類似
#!/bin/bash
#Name?? : Mulloop
#Author : Hijack
#Usage : break test
declare -i x=0
declare -i y=0
while true
do
while (( x<20 ))
do
?? x=$x+1
?? echo $x
?? if (( $x==10 ));then
??? echo "if"
??? break
?? fi
done
echo "loop end"
y=$y+1
if (($y>5));then
?? break
fi
done
[test@szbirdora 1]$ sh mulloop
1
2
3
4
5
6
7
8
9
10
if
loop end
11
12
13
14
15
16
17
18
19
20
loop end
loop end
loop end
loop end
loop end
#!/bin/bash
#Name?? : Mulloop
#Author : Hijack
#Usage : break test
declare -i x=0
declare -i y=0
while true
do
while (( x<20 ))
do
?? x=$x+1
?? echo $x
?? if (( $x==10 ));then
??? echo "if"
??? break 2
?? fi
done
echo "loop end"
y=$y+1
if (($y>5));then
?? break
fi
done
[test@szbirdora 1]$ sh mulloop
1
2
3
4
5
6
7
8
9
10
if
14.循環的IO重定向
使用">","|"等重定向符實現循環的IO重定向
如 while ;do
????? done >temp$$
??? for in
??? do
??? done |sort
eg
給文件的每行加一個行號,寫入文件中
#!/bin/bash
#Name??? : loopred
#Author : Hijack
#Usage?? : add linenum to the file
#Program : read line to loop from file,add linenum,output to tempfile,mv tempfile to file
declare -i count=0
declare -i total=0
total=`sed -n "$=" $1`
cat $1 | while read line
do
??? (($count==0))&& echo -e "Processing file $1.....\n"> /dev/tty
??? count=$count+1
??? echo -e "$count\t$line"
??? (($count==$total))&& echo "Process finish,total line number is $count" > /dev/tty
done >temp$$
mv temp$$ $1
[test@szbirdora 1]$ sh loopred testmv
Processing file testmv.....
Process finish,total line number is 19
[test@szbirdora 1]$ vi testmv
1?????? /u01/test
2?????? /u01/test/1
3?????? /u01/test/1/11
4?????? /u01/test/1/forlist.sh
5?????? /u01/test/1/optgets.sh
6?????? /u01/test/1/whiletest.sh
7?????? /u01/test/1/func.sh
8?????? /u01/test/1/helloworld.sh
9?????? /u01/test/1/df.out
10????? /u01/test/1/nullfile.txt
11????? /u01/test/1/iftest.sh
12????? /u01/test/1/myfile
13????? /u01/test/1/opt2.sh
14????? /u01/test/1/0
15????? /u01/test/1/case.sh
16????? /u01/test/1/nohup.out
17????? /u01/test/1/hellfun.sh
18????? /u01/test/1/parm.sh
19????? /u01/test/1/test
15。在done后面加&使循環在后臺運行,程序繼續執行。
16.在函數內可以使用local定義本地變量,local variable。
17.陷阱信號 trap --當一個信號發出傳遞給進程時,進程進行相關操作,信號包括中斷等
???? trap ‘command;command’ signal-num????????????????????????? #trap設置時執行命令
???? trap “command;command” signal-num???????????????????????? #信號到達時執行命令
eg:
[root@linux2 ~]# trap "echo -e 'hello world\n';ls -lh" 2
[root@linux2 ~]# hello world???????????????????????????????????????????? ---ctrl+c
total 100K
-rw-r--r-- 1 root root 1.4K Nov 14 16:53 anaconda-ks.cfg
drwxr-xr-x 2 root root 4.0K Nov 23 13:11 Desktop
-rw-r--r-- 1 root root 53K Nov 14 16:53 install.log
-rw-r--r-- 1 root root 4.9K Nov 14 16:53 install.log.syslog
drwxr-xr-x 2 root root 4.0K Nov 22 13:03 vmware
總結
以上是生活随笔為你收集整理的Linux Shell实例精讲学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: shell 实例收集
- 下一篇: linux shell编程控制结构:ex