篇幅有點長,但是認真看完對你是有很大幫助。 ## -print 將匹配的文件輸出到標準輸出## -exec 將匹配的文件執行該參數所給出的shell命令## -ok 將匹配的文件執行該參數所給出的shell命令,每次執行命令有提示 # find /etc -name passwd -exec rm ...
篇幅有點長,但是認真看完對你是有很大幫助。
## -print 將匹配的文件輸出到標準輸出
## -exec 將匹配的文件執行該參數所給出的shell命令
## -ok 將匹配的文件執行該參數所給出的shell命令,每次執行命令有提示
#-------------------------------------------------------------
find /etc -name passwd -exec rm {} \; ## {} \;中間有空格,不提示
find /etc -name passwd -ok rm {} \; ## {} \;中間有空格,每次刪除都提示
#-------------------------------------------------------------
## -prune 不在指定的目錄中查找,不可以與-depth選項連用
案例一:查找/home目錄下所有的.sh結尾的文件,忽略/home/ab目錄
註意:不可以寫成-path '/home/ab/' ; 要註意此命令的路徑寫法,要不同為絕對路徑,要不同為相對路徑;否則就為錯誤
[root@localhost home]# find /home -path '/home/ab' -prune -o -name '*.sh' -print
/home/t1.sh
/home/t2.sh
/home/t3.sh
/home/t4.sh
/home/t5.sh
/home/t6.sh
/home/t7.sh
/home/t8.sh
/home/t9.sh
[root@localhost home]# find . -path './ab' -prune -o -name '*.sh' -print
./t1.sh
./t2.sh
./t3.sh
./t4.sh
./t5.sh
./t6.sh
./t7.sh
./t8.sh
./t9.sh
[root@localhost home]#
#################################################################################
案例二:在除dir0、dir1及子目錄以外的目錄下查找txt尾碼文件
find ./ \( -path './dir0*' -o -path './dir1*' \) -a -prune -o -name *.txt -print
註意:圓括弧()表示此處是一個複合表達式,它告訴 shell 不對圓括弧裡面的字元作特殊解釋,而留給 find 命令去解釋其意義。由於命令行不能直接使用圓括弧,所以需要用反斜杠’\’進行轉意。一定要註意’(‘,’)’左右兩邊都需空格。
#################################################################################
案例三: 在dir0、dir1及子目錄下查找txt尾碼文件
find ./ \( -path './dir0*' -o -path './dir1*' \) -a -name *.txt -print
---------------------
-perm 按照文件許可權來查找文件
-mtime -n 文件更改時間距離現在n天以內
-mtime +n 文件更改時間距離現在n天以前
-atime
-ctime
---------------------
xargs -exec 區別
-exec: 對傳遞給exec執行的文件長度有限制;對處理的每一個匹配到的文件發起一個進程.
xargs: 每次只獲取一部分文件而不是全部文件,對處理的所有文件只有一個進程
---------------------------
案例一:
[root@localhost home]# ls
a ab jack t1.sh t2.sh t3.sh t4.sh t5.sh t6.sh t7.sh t8.sh t9.sh
[root@localhost home]# find /home -name "*.sh" | xargs chmod 777 ##對匹配到的文件統一授權
[root@localhost home]# find /home -name "*.sh" -exec chmod 000 {} \; ##對匹配到的文件統一授權
################
後臺執行命令
################
atq 查詢後臺執行的命令
atrm 刪除後臺執行的命令
nohup 進程在退出帳戶時該進程還不會結束,可以使用此命令
格式: nohup command &
[root@localhost home]# nohup ping 127.0.0.1 &
[2] 11319
[root@localhost home]# nohup: 忽略輸入並把輸出追加到"nohup.out"
[root@localhost home]# ls nohup.out
nohup.out
[root@localhost home]# jobs -l #查看後臺運行的進程
[2]+ 11319 運行中 nohup ping 127.0.0.1 &
[root@localhost home]#
################
文件名置換
################
[...] 匹配[]中所含有的任何字元
[!...] 匹配[]中非感嘆號!之後的字元
echo命令有很多功能,使用的時候需要加選項"-e"; 最常用的是下麵幾個:
\\ 反斜線
\a 報警符(BEL)
\b 退格符
\c 禁止尾隨的換行符
\f 換頁符
\n 換行符
\r 回車符
\t 水平製表符
\v 縱向製表符
-n 不輸出行尾的換行符.
-e 允許對下麵列出的加反斜線轉義的字元進行解釋.
案例一:
echo -e "what is your name: \c"
read name
echo 你的名字是:$name
等價於
echo -n "what is your name:"
read name
echo 你的名字是:$name
## read 命令
語法: read varible1 varible2 ...
案例一: 執行時一次性需要輸入2個參數
echo -n "輸入你的名字和別名: "
read name alia
echo 你的名字是:$name 你的別名是: $alia
## tee 命令
把輸出的一個副本輸送到標準輸出,另一個
副本拷貝到相應的文件中。
tee -a files # -a表示追加到文件末尾
案例一: 將文件追加到nohup.out末尾
[root@localhost home]# head -4 /etc/passwd | tee -a nohup.out
command 1> filename #把標準輸出重定向到一個文件中
command 1> filename 2>&1 #把標準輸出和標準錯誤重定向到一個文件中
案例一: 將錯誤文件和正確文件輸出到filename
cat>>filename 2>&1<<EOF
EOF
## exec命令
exec使用當前shell,沒有開啟子shell,執行的時候所有的環境
都將會被清除,並重新啟動一個shell;執行完畢後關閉shell
################
命令執行順序
################
(命令1;命令2;....) 在當前shell中執行
{命令1;命令2;....} 在當前子shell中執行
################
正則表達式
################
pattern\n{n\} 用來匹配前面pattern出現次數,n為次數
pattern\{n,\} 用來匹配前面pattern至少為n次
pattern\{n,m\} 用來匹配前面pattern出現次數為n與m次之間
#-----------------------------------------------------
案例一:
0 - 9 ] \ { 2 \ } - [ 0 - 9 ] \ { 2 \ } - [ 0 - 9 ] \ { 4 \ } ##對日期格式d d - m m - y y y y
[ 0 - 9 ] \ { 3 \ } \ . [ 0 - 9 ] \ { 3 \ } \ . [ 0 - 9 ] \ { 3 \ } \ . [ 0 - 9 ] \ { 3 \ } ##對I P地址格式nnn. nnn.nnn.nnn
[ ^ . * $ ] ##對匹配任意行
#-----------------------------------------------------
sort 預設按照第一列進行排序操作,以空格進行分割
sort -t (設置分隔符)和-k (指定某列) filename
########
案例:
1. 指定冒號為分隔符,按照第四列排序
sort -t: -g -k4 /etc/passwd
2. -g表示以數值類型排序,預設按照字元串類型,即把數值當做字元串來比對
[root@localhost ~]# sort -t: -g -k3 passwd #-g選項,按照常規數值排序
[root@localhost ~]# sort -t: -n -k3 passwd #-n選項,按照字元串數值排序
[root@localhost ~]# sort -t: -k3 passwd #把第三列作為常規類型排序,會2大於10類型的錯誤
3. -u 刪除重覆的內容
[root@localhost ~]# ls -l /etc | awk '{print $5}' | wc -l
292
[root@localhost ~]# ls -l /etc | awk '{print $5}' | sort -u |wc -l #sort -u去重
184
[root@localhost ~]#
##uniq的重覆表示行連續重覆,而sort -u的重覆則對所有行來說
案例一:
[root@localhost ~]# uniq -c aa #顯示aa文件中出現連續重覆的行的次數
2 test
1 admin
1 test
1 jack
1 liu
3 test
[root@localhost ~]#
[root@localhost ~]# uniq -d aa #顯示重覆出現的行
test
test
aa
vm
[root@localhost ~]# uniq -f2 aa #查看第二域,忽略第一域,查看有重覆的項
test aa
[root@localhost ~]#
##cut 剪切列或域
-d #指定與空格和Tab鍵不同的域分隔符
-f1,5 #剪切第1域,第5域
################################
paste:
-d #連接2個文件的連接分隔符,例如-d@
[root@localhost ~]# paste aa bb #將2個文件按照行合併
aroot admin docker aa
aroot admin oa bb
aroot admin
aroot admin
jack public
[root@localhost ~]#
#第一個文件作為第一行,第二個作為第二行
[root@localhost ~]# paste -s aa bb
aroot admin aroot admin aroot admin aroot admin jack public
docker aa oa bb
[root@localhost ~]#
#以空格進行分割,每行只顯示2列內容
[root@localhost ~]# ls /etc | paste -d" " - -
################
登錄環境
################
用戶登錄時,自動讀取/etc目錄下profile文件,此文件包含:
? 全局或局部環境變數。
? PATH信息。
? 終端設置。
? 安全命令。
? 日期信息或放棄操作信息。
stty用於設置終端特性.
stty -a #查看終端現在的stty選項
[root@localhost ~]# stty -a
speed 38400 baud; rows 28; columns 143; line = 0;
intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z;
rprnt = ^R; werase = ^W; lnext = ^V; flush = ^O; min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl ixon -ixoff -iuclc -ixany -imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke
#############################
案例一: 避免鍵盤上輸入錯誤無法刪除
#!/bin/bash
echo -n "請輸入你的名字:"
stty erase '^H' #避免鍵盤上輸入錯誤無法刪除
read name
echo 你的名字為: $name
###########################
案例二:關閉回顯功能
#!/bin/bash
#將終端特性保存為一個變數
savestty=`stty -g`
#更改終端特性echo
stty cbreak -echo
stty -a
echo -e "\nGive me that passwd: \c"
read passwd
echo -e "\nyou password is $passwd"
#恢復終端特性為保存的變數
stty $savestty
[root@localhost ~]#
#-----------------------------------------------------------------------
################
環境變數
################
unset 清除變數
set 查看所有本地定義的shell變數
${變數名:-變數值} #如果未初始化則使用花括弧裡面的變數值
#################################
#!/bin/bash
aab=vmsys
echo ${aab:-redhat} #如果變數沒有設置初始值,則變數值為redhat
#################################
[root@localhost ~]# more ab.sh
#!/bin/bash
aab=vmsys
echo 變數內容為:${aab:-redhat} #如果變數沒有設置初始值,則變數值為redhat
#------------- ------------------------------
color=blue
echo "未清除變數內容為: ${color:-grey}"
unset color #清除變數後,變數值為花括弧裡面內容
echo "清除後變數內容為: ${color:-grey}"
[root@localhost ~]# sh ab.sh
變數內容為:vmsys
未清除變數內容為: blue
清除後變數內容為: grey
[root@localhost ~]#
################
案例三:
#!/bin/bash
echo -n "what time do you wish to start the payrool: [03:00] "
read TIME
echo "process to start at ${TIME:=03:00} ok"
echo -n "is it a monthly or weekly run [weekly]"
read RUN_TYPE
echo "Run type is ${RUN_TYPE:=weekly}"
at -f $RUN_TYPE $TIME #-f表示一次性計劃任務從文件讀取
####
案例四: 提示信息自己定義的內容 ${變數名:? "提示內容..."}
echo "the file is ${files:? "sorry cannot locate the variable files"}"
[root@localhost ~]#
案例五:
#echo ${var0?jack} #未定義變數var0,則顯示自定義的提示字元串jack
#echo ${var1:?jack} #未定義變數var1,則顯示自定義的提示字元串jack
#echo ${var2:-jack} #沒有設置var2的時候,後續echo $var2為空,當前${var2:-jack}代碼顯示為jack,屬於一種替換操作!
#echo ${var3:=jack} #沒有定義var3自動設置var3=jack;如果設置了變數就使用定義的
###########################################################################
測試變數是否取值,如果未設置,則返回一空串。方法如下:
$ { v a r i a b l e : + v a l u e }
案例1:
abc=100
echo ${abc+`route add default gw 172.16.38.254`} #如果沒有定義變數abc就顯示為空,定義了就執行後面命令
#######################################
在腳本中調用另一腳本(這實際上創建了一個子進程)
在一個腳本調用另外一個腳本需要設置PATH環境變數,並且還需要export導出;
案例一:
[root@localhost ~]# more father
#!/bin/bash
PATH=$PATH:/root
export PATH
echo "This is the father"
FILM="A few good Men"
echo "I like the film: $FILM"
export FILM
echo ------------------------------
child
echo "back to father"
echo "and the film is: $FILM"
[root@localhost ~]# more child
#!/bin/bash
echo "called from father.. i am the child"
echo "film name is: $FILM"
FILM="DIE HARD"
echo "changing film to: $FILM"
[root@localhost ~]#
###############
$# 傳遞到腳本的參數個數
$* 以一個單字元串顯示所有向腳本傳遞的參數
$$ 腳本運行的當前進程ID號
$! 後臺運行的最後一個進程的進程ID號
$@ 與$#相同,但是使用是要加上引號
$- 顯示shell使用的當前選項,與set命令功能相同
[ -r filename -a -w filename ] #文件filename可讀可寫
或者
[ -r filename ] && [ -w filename ]
#######################################
字元串類型:
= 字元串相等
!= 字元串不等
-z 空串
-n 非空串
---------------------------------------
#############
流控制部分
#############
#!/bin/bash
echo "`basename $0`" #表示執行的變數本身
####################################
>&2 也就是把結果輸出到和標準錯誤一樣
###將每行做為一個單變數輸入到line
#!/bin/bash
while read line
do
echo $line
done< filename.txt
#--------------------------------------------
#!/bin/bash
#root x 0 0 root /root /bin/bash
#bin x 1 1 bin /bin /sbin/nologin
###################################################
save_ifs=$IFS #保存預設分隔符
IFS=: #設置分隔符為冒號
while read A B C D E F G #讀取七個變數
do
echo -e "$A\t$B\t$C\t$D\t$E\t$F\t$G\t" #設置分隔符為\t
done < /etc/passwd
IFS=$save_ifs #恢復預設分隔符
#----------------------------------------------
total=`expr ${total:=0} + ${items:=100}`
#####################
read每次讀取2條記錄
#------------
#!/bin/bash
while read rec1
do
read rec2
echo "one:"$rec1
echo "two:"$rec2
echo ------------------------------
done</etc/passwd
################################################
#當為數字的時候awk返回為1
[root@localhost ~]# echo 22 | awk '{if($0~/[^a-z A-Z]/) print "1"}'
1
[root@localhost ~]#
# 不能含有空格或者字母,否則返回1
[root@localhost ~]# echo 22 2 | awk '{if($0~/[a-zA-Z ]/) print "1"}'
1
[root@localhost ~]#
#-----------------------------------
do
{語句}
while(條件)
例子:
[chengmo@localhost nginx]# awk 'BEGIN{
total=0;
i=0;
do
{
total+=i;
i++;
}while(i<=100)
print total;
}'
結果: 5050
#!/bin/bash
read -p "請輸入內容: " var
aa=`echo $var | awk '{if($0~/[a-zA-Z]/) print "1";else if($0~/[0-9]/) print "2"}'`
echo $aa
## shfit 向左偏移一位
#!/bin/bash
while [ $# -ne 0 ]
do
echo $1
shift
done
~
###########################
擴展AWK
###########################
1.
[root@localhost ~]# awk '(/^root/) {print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# awk '/^root/ {print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]#
2. NF表示讀取的域數
[root@localhost ~]# awk 'BEGIN{FS=":"} /^root/ {print $1,$NF}' /etc/passwd
root /bin/bash
[root@localhost ~]#
3.NR表示讀取的記錄數
[root@localhost ~]# awk 'BEGIN{FS=":"} /^root/ {print NR,$1,$NF}' /etc/passwd
1 root /bin/bash
[root@localhost ~]#
4.OFS="##" 輸出字元串使用##
[root@localhost ~]# awk 'BEGIN{FS=":";OFS="##"} /^root/ {print NR,$1,$NF}' /etc/passwd
1##root##/bin/bash
[root@localhost ~]#
5.設置輸出欄位分隔符(OFS使用方法)
[chengmo@localhost ~]$ awk 'BEGIN{FS=":";OFS="^^"}/^root/{print FNR,$1,$NF}' /etc/passwd
1^^root^^/bin/bash
6.設置輸出行記錄分隔符(ORS使用方法)
[chengmo@localhost ~]$ awk 'BEGIN{FS=":";ORS="^^"}{print FNR,$1,$NF}' /etc/passwd
1 root /bin/bash^^2 bin /sbin/nologin^^3 daemon /sbin/nologin^^4 adm /sbin/nologin^^5 lp /sbin/nologin
從上面看,ORS預設是換行符,這裡修改為:”^^”,所有行之間用”^^”分隔了。
7.ARGC得到所有輸入參數個數,ARGV獲得輸入參數內容,是一個數組
[root@localhost ~]# awk 'BEGIN{FS=":"; print "ARGC="ARGC; for(k in ARGV) {print k"=" ARGV[k];} } ' /etc/passwd ADMIN JACK
ARGC=4
0=awk
1=/etc/passwd
2=ADMIN
3=JACK
[root@localhost ~]#
8.獲取環境變數;ENVIRON是子典型數組,可以通過對應鍵值獲得它的值。
[root@localhost ~]#
[root@localhost ~]# awk 'BEGIN{print ENVIRON["PATH"];}' /etc/passwd
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin
[root@localhost ~]#
[root@localhost ~]#
9.格式如:awk ‘{action}’ 變數名=變數值 ,這樣傳入變數,可以在action中獲得值。 註意:變數名與值放到’{action}’後面
[root@localhost ~]# aa='bdqn jack'
[root@localhost ~]#
[root@localhost ~]# echo | awk '{print aa}' aa="$aa"
bdqn jack
[root@localhost ~]#
10.只需要調用:awk內置變數 ENVIRON,就可以直接獲得環境變數。它是一個字典數組。環境變數名 就是它的鍵值。
awk 'BEGIN{for (i in ENVIRON) {print i"="ENVIRON[i];}}'
11.true就返回1,false返回0
awk邏輯運算符
[chengmo@localhost ~]$ awk 'BEGIN{a=1;b=2;print (a>5 && b<=2),(a>5 || b<=2);}'
0 1
12. ?:運算符
[chengmo@localhost ~]$ awk 'BEGIN{a="b";print a=="b" ? "ok":"err";}'
ok
[root@localhost ~]# awk 'BEGIN{a="b";print a!="b" ? "ok":"err";}'
err
13. in運算符;in運算符,判斷數組中是否存在該鍵值
[chengmo@localhost ~]$ awk 'BEGIN{a="b";arr[0]="b";arr[1]="c";print (a in arr);}'
0
[chengmo@localhost ~]$ awk 'BEGIN{a="b";arr[0]="b";arr["b"]="c";print (a in arr);}'
1
in運算符,判斷數組中是否存在該鍵值
14.只需要將變數通過”+”連接運算。自動強制將字元串轉為整型。非數字變成0,發現第一個非數字字元,後面自動忽略。10test10忽略後面的test10變成==>>10
[chengmo@centos5 ~]$ awk 'BEGIN{a="100";b="10test10";print (a+b+0);}'
110
15.awk數字轉為字元串
[chengmo@centos5 ~]$ awk 'BEGIN{a=100;b=100;c=(a""b);print c}'
100100
只需要將變數與””符號連接起來運算即可
16.
[chengmo@centos5 ~]$ awk 'BEGIN{a="a";b="b";c=(a""b);print c}'
ab
[chengmo@centos5 ~]$ awk 'BEGIN{a="a";b="b";c=(a+b);print c}'
0
字元串連接操作通”二“,”+”號操作符。模式強制將左右2邊的值轉為 數字類型。然後進行操作。
17.數組的使用;split為分割字元串為數組
[root@localhost ~]# awk 'BEGIN{info="it is a test";lens=split(info,tA," ");print length(tA), tA[1],tA[2];}'
4 it is
[root@localhost ~]#
[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";split(info,tA," ");print asort(tA);}'
4
asort對數組進行排序,返回數組長度。
18. 迴圈列印數組
[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";split(info,tA," ");for(k in tA){print k,tA[k];}}'
4 test
1 it
2 is
3 a
for…in 輸出,因為數組是關聯數組,預設是無序的。所以通過for…in 得到是無序的數組。如果需要得到有序數組,需要通過下標獲得。
[chengmo@localhost ~]$ awk 'BEGIN{info="it is a test";tlen=split(info,tA," ");for(k=1;k<=tlen;k++){print k,tA[k];}}'
1 it
2 is
3 a
4 test
註意:數組下標是從1開始,與c數組不一樣。
19.判斷數組
正確判斷方法:
[chengmo@localhost ~]$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";if( "c" in tB){print "ok";};for(k in tB){print k,tB[k];}}'
a a1
b b1
if(key in array) 通過這種方法判斷數組中是否包含”key”鍵值。
20.刪除鍵值:
[chengmo@localhost ~]$ awk 'BEGIN{tB["a"]="a1";tB["b"]="b1";delete tB["a"];for(k in tB){print k,tB[k];}}'
b b1
delete array[key]可以刪除,對應數組key的,序列值
21. 多重嵌套,每條命令語句後面可以用“;”號結尾
awk 'BEGIN{
test=100;
if(test>90)
{
print "very good";
}
else if(test>60)
{
print "good";
}
else
{
print "no pass";
}
}'
22.
awk 'BEGIN{
test=100;
total=0;
while(i<=test)
{
total+=i;
i++;
}
print total;
}'
5050
23. for迴圈
for迴圈有兩種格式:
格式1:
for(變數 in 數組)
{語句}
格式2:
for(變數;條件;表達式)
{語句}
案例:
awk 'BEGIN{
for(k in ENVIRON)
{
print k"="ENVIRON[k];
}
}'
#------------------
awk 'BEGIN{
total=0;
for(i=0;i<=100;i++)
{
total+=i;
}
print total;
}'
5050
24.do迴圈
格式:
do
{語句}while(條件)
案例:
awk 'BEGIN{
total=0;
i=0;
do
{
total+=i;
i++;
}while(i<=100)
print total;
}'
5050
## 案例:將具有字元串 ae 或 alle 或 anne 或 allnne 的所有記錄列印至標準輸出
在正則表達式中將字元串組合在一起。命令行:
awk '/a(ll)?(nn)?e/' testfile
## 內置函數:
#+ 表示匹配前面的子表達式一次或多次。要匹配 + 字元,請使用 \+
awk 'BEGIN{info="this is a test2010test!";gsub(/[0-9]+/,"!",info);print info}'
this is a test!test!
#-------------------------------------------------------------------------------
gsub( Ere, Repl, [ In ] ) 除了正則表達式所有具體值被替代這點,它和 sub 函數完全一樣地執行,。
sub( Ere, Repl, [ In ] ) 用 Repl 參數指定的字元串替換 In 參數指定的字元串中的由 Ere 參數指定的擴展正則表達式的第一個具體值。
sub 函數返回替換的數量。出現在 Repl 參數指定的字元串中的 &(和符號)由 In 參數指定的與 Ere 參數的
指定的擴展正則表達式匹配的字元串替換。如果未指定 In 參數,預設值是整個記錄($0 記錄變數)。
index( String1, String2 ) 在由 String1 參數指定的字元串(其中有出現 String2 指定的參數)中,返回位置,從 1 開始編號。
如果 String2 參數不在 String1 參數中出現,則返回 0(零)。
length [(String)] 返回 String 參數指定的字元串的長度(字元形式)。如果未給出 String 參數,則返回整個記錄的長度($0 記錄變數)。
blength [(String)] 返回 String 參數指定的字元串的長度(以位元組為單位)。如果未給出 String 參數,則返回整個記錄的長度($0 記錄變數)。
substr( String, M, [ N ] ) 返回具有 N 參數指定的字元數量子串。子串從 String 參數指定的字元串取得,其字元以 M 參數指定的位置開始。
M 參數指定為將 String 參數中的第一個字元作為編號 1。如果未指定 N 參數,則子串的長度將是 M 參數指定的位置到 String 參數的末尾 的長度。
match( String, Ere ) 在 String 參數指定的字元串(Ere 參數指定的擴展正則表達式出現在其中)中返回位置(字元形式),
從 1 開始編號,或如果 Ere 參數不出現,則返回 0(零)。RSTART 特殊變數設置為返回值。RLENGTH 特殊變數設置為匹配的字元串的長度,或如果未找到任何匹配,則設置為 -1(負一)。
split( String, A, [Ere] ) 將 String 參數指定的參數分割為數組元素 A[1], A[2], . . ., A[n],並返回 n 變數的值。
此分隔可以通過 Ere 參數指定的擴展正則表達式進行,或用當前欄位分隔符(FS 特殊變數)來進行(如果沒有給出 Ere 參數)。除非上下文指明特定的元素還應具有一個數字值,否則 A 數組中的元素用字元串值來創建。
tolower( String ) 返回 String 參數指定的字元串,字元串中每個大寫字元將更改為小寫。大寫和小寫的映射由當前語言環境的 LC_CTYPE 範疇定義。
toupper( String ) 返回 String 參數指定的字元串,字元串中每個小寫字元將更改為大寫。大寫和小寫的映射由當前語言環境的 LC_CTYPE 範疇定義。
sprintf(Format, Expr, Expr, . . . ) 根據 Format 參數指定的 printf 子常式格式字元串來格式化 Expr 參數指定的表達式並返回最後生成的字元串。
#################################################
格式化字元串輸出(sprintf使用)
格式化字元串格式:
其中格式化字元串包括兩部分內容: 一部分是正常字元, 這些字元將按原樣輸出; 另一部分是格式化規定字元, 以"%"開始, 後跟一個或幾個規定字元,用來確定輸出內容格式。
格式符 說明
%d 十進位有符號整數
%u 十進位無符號整數
%f 浮點數
%s 字元串
%c 單個字元
%p 指針的值
%e 指數形式的浮點數
%x %X 無符號以十六進位表示的整數
%o 無符號以八進位表示的整數
%g 自動選擇合適的表示法
###############################################
函數名 說明
atan2( y, x ) 返回 y/x 的反正切。
cos( x ) 返回 x 的餘弦;x 是弧度。
sin( x ) 返回 x 的正弦;x 是弧度。
exp( x ) 返回 x 冪函數。
log( x ) 返回 x 的自然對數。
sqrt( x ) 返回 x 平方根。
int( x ) 返回 x 的截斷至整數的值。
rand( ) 返回任意數字 n,其中 0 <= n < 1。
srand( [Expr] ) 將 rand 函數的種子值設置為 Expr 參數的值,或如果省略 Expr 參數則使用某天的時間。返回先前的種子值。
####################################
## 獲取隨機數
[root@localhost ~]# awk 'BEGIN{srand();fr=int(10*rand());print fr;}'
7
[root@localhost ~]#
## AWK擴展用法
1. getline 變數名
[root@localhost ~]# awk 'BEGIN{print "Enter your name:";getline name;print name;}'
Enter your name:
hello
hello
[root@localhost ~]#
[root@localhost home]# awk 'BEGIN{while(getline < "/etc/passwd"){print $0;};close("/etc/passwd");}' | head -2
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
逐行讀取外部文件(getline使用方法)
[root@localhost home]# awk 'BEGIN{while("cat /etc/passwd"|getline){print $0;};close("/etc/passwd");}' | head -2
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@localhost home]#
##合併文件案例:
1.
[root@localhost home]# more a.txt
100 wang man
200 wangsan woman
300 wangming man
400 wangzheng man
[root@localhost home]# more b.txt
100 90 80
200 80 70
300 60 50
400 70 20
[root@localhost home]# awk '{printf("%s ", $0); getline<"b.txt" ;print $2,$3}' a.txt
100 wang man 90 80
200 wangsan woman 80 70
300 wangming man 60 50
400 wangzheng man 70 20
[root@localhost home]#
#
#### next 用法
#讀取文件的偶數行
當記錄行號除以2餘 1,就跳過當前行。下麵的print NR,$0也不會執行。 下一行開始,程式有開始判斷NR%2 值。
這個時候記錄行號是:2 ,就會執行下麵語句塊:'print NR,$0'
[root@localhost home]# more a.txt
100 wang man
200 wangsan woman
300 wangming man
400 wangzheng man
[root@localhost home]# awk 'NR%2==1 {next} {print NR,$0}' a.txt
2 200 wangsan woman
4 400 wangzheng man
[root@localhost home]#
2. 變數名=system("命令")
[root@localhost home]# awk 'BEGIN{b=system("ls -al");print b;}'
總用量 4
drwxr-xr-x. 3 root root 18 12月 13 09:02 .
dr-xr-xr-x. 20 root root 4096 12月 13 08:03 ..
drwx------. 5 jack jack 128 12月 10 16:36 jack
0
[root@localhost home]#
## 時間函數#
函數名 說明
----------------------------- ------------------------------------------
mktime( YYYY MM DD HH MM SS[ DST]) 生成時間格式
strftime([format [, timestamp]]) 格式化時間輸出,將時間戳轉為時間字元串
systime() 得到時間戳,返回從1970年1月1日開始到當前時間(不計閏年)的整秒數
#########
strftime日期和時間格式說明符
格式 描述
%a 星期幾的縮寫(Sun)
%A 星期幾的完整寫法(Sunday)
%b 月名的縮寫(Oct)
%B 月名的完整寫法(October)
%c 本地日期和時間
%d 十進位日期
%D 日期 08/20/99
%e 日期,如果只有一位會補上一個空格
%H 用十進位表示24小時格式的小時
%I 用十進位表示12小時格式的小時
%j 從1月1日起一年中的第幾天
%m 十進位表示的月份
%M 十進位表示的分鐘
%p 12小時表示法(AM/PM)
%S 十進位表示的秒
%U 十進位表示的一年中的第幾個星期(星期天作為一個星期的開始)
%w 十進位表示的星期幾(星期天是0)
%W 十進位表示的一年中的第幾個星期(星期一作為一個星期的開始)
%x 重新設置本地日期(08/20/99)
%X 重新設置本地時間(12:00:00)
%y 兩位數字表示的年(99)
%Y 當前月份
%Z 時區(PDT)
%% 百分號(%)
##########################
[root@localhost home]# awk 'BEGIN{tstamp=mktime("2001 01 01 12 12 12");print strftime("%c",tstamp);}'
2001年01月01日 星期一 12時12分12秒
[root@localhost home]#
求2個時間段中間時間差,介紹了strftime使用方法
[root@localhost home]# awk 'BEGIN{tstamp1=mktime("2001 01 01 12 12 12");tstamp2=mktime("2001 02 01 0 0 0");print tstamp2-tstamp1;}'
2634468
[root@localhost home]#
###@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
break 當 break 語句用於 while 或 for 語句時,導致退出程式迴圈。
continue 當 continue 語句用於 while 或 for 語句時,使程式迴圈移動到下一個迭代。
next 能能夠導致讀入下一個輸入行,並返回到腳本的頂部。這可以避免對當前輸入行執行其他的操作過程。
exit 語句使主輸入迴圈退出並將控制轉移到END,如果END存在的話。如果沒有定義END規則,或在END中應用exit語句,則終止腳本的執行
###@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
###########################
AWK
----------
模式部分: 決定動作語句何時出發及觸發事件,如果省略將時刻保持執行狀態.
動作部分: 在大括弧{ }內指明.
模式:
BEGIN.....END.....
begin: 設置計數和列印頭
end:完成文本瀏覽動作後列印輸出文件總數和結尾狀態標記.
####################################################
{ } 花括弧裡面的是動作, ( )圓括弧裡面的是條件
---------------------------------------------------
案例一:
awk 'BEGIN {print "Name\n-------"} {print $1} END {"end-of-report"}' grade.txt
案例二:
awk -F ":" '$4=="50"' /etc/passwd
awk -F ":" '{if($1~/root/) print $0}' /etc/passwd
awk -F ":" '$4=="50" {print $0}' /etc/passwd
[root@localhost ~]# awk '/bash/' /etc/passwd
案例三:
[root@localhost ~]# awk -F ":" '{if($3<$4) print $0 "--------"}' /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin--------
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin--------
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin--------
games:x:12:100:games:/usr/games:/sbin/nologin--------
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin--------
[root@localhost ~]#
案例四: 定義變數t=0,匹配到每次加1,末尾列印內容
[root@localhost ~]# awk 'BEGIN{t=0} {if($0~/bash$/) t++} END{ print t}' /etc/passwd
2
[root@localhost ~]#
[root@localhost ~]# awk '$0~/(root|jack)/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
jack:x:1000:1000:jack:/home/jack:/bin/bash
dockerroot:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
[root@localhost ~]#
案例五: && || !
[root@localhost ~]# awk '{if($3 > $2 && $0~/rpc/) print $0}' /etc/passwd
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
[root@localhost ~]#
##內置變數
NF 瀏覽記錄的域個數
NR 已讀取的記錄數
[root@localhost ~]# awk 'END{print NR}' /etc/passwd #輸入文件的記錄數
49
[root@localhost ~]#
[root@localhost ~]# awk -F ":" 'END{print NF,NR,FILENAME}' /etc/passwd
7 49 /etc/passwd
# NF表示以冒號做分隔讀取了幾個區域;
# NR表示讀取的記錄數;
# FILENAME表示文件名
#===============================
[root@localhost ~]# awk -F ":" '{if($0~/bash/ && $3=$4 && NR>0) print $0}' /etc/passwd
jack x 1 1000 jack /home/jack /bin/bash
[root@localhost ~]#
[root@localhost network-scripts]# echo $PWD | awk -F / '{print NF}'
4
[root@localhost network-scripts]# echo $PWD | awk -F / '{print $NF}'
network-scripts
[root@localhost network-scripts]# echo $PWD | awk -F / '{print $4}'
network-scripts
#定義變數bline為3,當第三列小於3的時候列印滿足條件全部內容
[root@localhost ~]# awk -F ":" 'BEGIN {bline=3} {if ($3<bline) print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]#
##### 當條件有多個圓括弧的時候需要添加分號 ############
#域值修改
[root@localhost ~]# awk -F ":" '{if($1=="root") $3=$3+100; print $1,$3}' aa
root 100
bin 1
daemon 2
[root@localhost ~]# more aa
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]#
#對匹配到的字元串,進行重新變數賦值
[root@localhost ~]# awk -F ":" '{if($1=="root")($1="admin") ; print $0}' aa
admin x 0 0 root /root /bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@localhost ~]#
## 模式後面 使用花括弧將只對修改的部分進行顯示結果
[root@localhost ~]# awk -F ":" '{if($1=="root") {$1="admin" ; print $0} }' aa
admin x 0 0 root /root /bin/bash
[root@localhost ~]#
[root@localhost ~]# awk -F ":" '{if($1=="root") ($1="admin") ($3=$3+100); { print $0} }' aaadmin x 100 0 root /root /bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
## 模式後面 使用花括弧將只對修改的部分進行顯示結果
[root@localhost ~]# awk -F ":" '{if($1=="root") {($1="admin")($3=$3+100); print $0} }' aa
admin x 100 0 root /root /bin/bash
[root@localhost ~]#
## 創建新域列 $10
[root@localhost ~]# awk -F ":" '{if($1=="root") {($1="admin")($10=$3+100); print $10} }' aa
100
[root@localhost ~]#
## 創建自定義列
[root@localhost ~]# awk -F ":" 'BEGIN {print "Uname \t\t Login"} {if($3<$4) print $1,"\t\t"$7}' /etc/passwd
Uname Login
adm /sbin/nologin
lp /sbin/nologin
mail /sbin/nologin
games /sbin/nologin
ftp /sbin/nologin
[root@localhost ~]#
## 將整個文件的第三域相加
[root@localhost ~]# awk -F ":" '(total+=$3); END{print "第三列相加結果為: "total}' aa
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
第三列相加結果為: 3
[root@localhost ~]#
## 只顯示匹配的內容
[root@localhost ~]# awk -F ":" '{(total+=$3)}; END{print "第三列相加結果為: "total}' aa
第三列相加結果為: 3
[root@localhost ~]#
## 創建變數tot,設置自動相加,在結尾列印彙總結果
[root@localhost ~]# ls -l | awk ' / ^[^X]/ {print $9 "\t" $5} {tot+=$5} END{print "彙總後結果為:" tot}'
彙總後結果為:14523
[root@localhost ~]#
######################
內置函數
######################
## 列印$1長度---->>> length()
[root@localhost ~]# awk -F ":" 'BEGIN {Uname "\t" Login} {if($3>$4) print length($1),$0}' /etc/passwd
4 sync:x:5:0:sync:/sbin:/bin/sync
8 shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
4 halt:x:7:0:halt:/sbin:/sbin/halt
8 operator:x:11:0:operator:/root:/sbin/nologin
7 polkitd:x:999:998:User for polkitd:/:/sbin/nologin
14 libstoragemgmt:x:998:996:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin
## gsub替換; 使用正則表達式替換, (/目標模式/,替換模式)
[root@localhost ~]# awk -F ":" 'gsub(/root/,"admin") {print $0}' /etc/passwd
admin:x:0:0:admin:/admin:/bin/bash
operator:x:11:0:operator:/admin:/sbin/nologin
dockeradmin:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
[root@localhost ~]#
[root@localhost ~]# awk -F: '{gsub(/bash/,"admin",$0);print $0}' passwd
root:x:0:0:root:/root:/bin/admin
root:x:0:0:/bin/admin:/root:/bin/admin
root:x:0:0:/bin/admin:/root:/bin/admin
jack:x:1000:1000:jack:/home/jack:/bin/admin
[root@localhost ~]#
## gsub()帶條件替換;當替換為字元串需要使用" ";替換內容為整形不需要" "
[root@localhost ~]# awk -F ":" '{if($3<$4) { print $0}}' /etc/passwd
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@localhost ~]# awk -F ":" '{if($3<$4) { gsub(/adm/,"jack");print $0}}' /etc/passwd
jack:x:3:4:jack:/var/jack:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
[root@localhost ~]#
#################################################################################
案例: 對比 sub() gsub()區別
#################################
#
#gsub()全局替換
#sub() 替換每行的第一個
#substr() 顯示指定string長度位置
#
#################################
[root@localhost ~]# more passwd 源文件
root:x:0:0:root:/root:/bin/bash
root:x:0:0:/bin/bash:/root:/bin/bash
root:x:0:0:/bin/bash:/root:/bin/bash
jack:x:1000:1000:jack:/home/jack:/bin/bash
[root@localhost ~]# awk -F: '$0~/bash/ {gsub(/bash/,"admin");print $0}' passwd #替換全文bash為admin
root:x:0:0:root:/root:/bin/admin
root:x:0:0:/bin/admin:/root:/bin/admin
root:x:0:0:/bin/admin:/root:/bin/admin
jack:x:1000:1000:jack:/home/jack:/bin/admin
[root@localhost ~]#
[root@localhost ~]# awk -F: '$0~/bash/ {sub(/bash/,"admin");print $0}' passwd #替換每行第一個bash為admin
root:x:0:0:root:/root:/bin/admin
root:x:0:0:/bin/admin:/root:/bin/bash
root:x:0:0:/bin/admin:/root:/bin/bash
jack:x:1000:1000:jack:/home/jack:/bin/admin
[root@localhost ~]#
###################################################################################
# substr(str,n,m) #顯示字元串str從n到m長度大小的內容
[root@localhost ~]# awk '$1~/root/ {print substr($1,1,2)}' /etc/passwd
ro
op
do
[root@localhost ~]# awk '$1~/root/ {print $0}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
dockerroot:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
[root@localhost ~]#
[root@localhost ~]# awk '$1~/root/ {print substr($1,1,2)}' /etc/passwd #
ro
op
do
[root@localhost ~]#
#
[root@localhost ~]# awk 'BEGIN {str="Iloveyou"}END{print substr(str,2)}' bb ##其中bb可以隨便寫,begin定義內容,end截取內容
loveyou
[root@localhost ~]#
## 查詢字元串s中t出現的第一位置,字元串需要用雙引號括起來. index( )
[root@localhost ~]# awk 'BEGIN {print index("root","o")}' /etc/passwd
2
## 測試目標字元串是否包含查找字元串的一部分,查找到了就返回所在位置,沒有找到就返回0
[root@localhost ~]# awk 'BEGIN {print match("ABCD",/D/)}'
4
[root@localhost ~]# awk 'BEGIN {print match("ABCD",/d/)}'
0
[root@localhost ~]#
## split 返回字元串數組元素個數
#將第一行切割為以冒號作為分隔符的數組
[root@localhost ~]# head -1 /etc/passwd | awk 'BEGIN{ } {print split($0,array,":")}'
7
[root@localhost ~]#
# sub(/替換前內容/,"替換後字元串",$0)
[root@localhost ~]# awk -F: '{if($1=="root") {print $0}}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# awk -F: '{if($1=="root") {sub(/root/,"admin",$0) ;print $0}}' /etc/passwd #sub(/root/,"admin",$0)中的$0可以不寫
admin:x:0:0:root:/root:/bin/bash
[root@localhost ~]#
### 定義變數AGE,向awk傳值
[root@localhost ~]# awk -F: '{if($3<AGE) print $0}' AGE=5 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[root@localhost ~]#
[root@localhost ~]# who
root pts/0 2018-12-12 09:19 (192.168.80.8)
[root@localhost ~]#
[root@localhost ~]# who | awk '{if($1==user) print $1 " You are connected to " $2}' user=$LOGNAME #傳遞變數
root You are connected to pts/0
[root@localhost ~]#
####################
將awk寫入到腳本文件
####################
#!/bin/awk -f
BEGIN { }
{ }
END { }
#############################################
#awk; 定義變數t,每次值加1,使用split()切割為數組, 使用for迴圈來遍曆數組內容
[root@localhost ~]# head -1 /etc/passwd |awk -F ":" 'BEGIN{t=0} {split($0,my,":")}END{for(i in my) {t+=1;print "my["t"]="my[i]}}'
my[1]=0
my[2]=root
my[3]=/root
my[4]=/bin/bash
my[5]=root
my[6]=x
my[7]=0
[root@localhost ~]#
####
sed
####
##
1. [root@localhost ~]# sed -n '10p' /etc/passwd
operator:x:11:0:operator:/root:/sbin/nologin
[root@localhost ~]#
2.[root@localhost ~]# sed -n '/^root/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]#
3. 模式與行號混合方式;格式: line_number,/pattern/
案例:
4,/the/ #表示查詢第四行的the
4. 列印模式匹配的行號,使用格式/pattern/=
[root@localhost ~]# sed -n -e '/root/p' -e '/root/=' /etc/passwd
root:x:0:0:root:/root:/bin/bash
1
operator:x:11:0:operator:/root:/sbin/nologin
10
dockerroot:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
48
[root@localhost ~]#
5. a\,可以將指定文本一行或多行附加到指定模式位置;"a\"中的反斜線表示換行
6. i\,可以將指定文本一行或多行插入到指定模式位置;"a\"中的反斜線表示換行
7. c\,將指定模式匹配的行替換;"c\"中的反斜線表示換行
8. d\,將指定模式匹配的行刪除;"d\"中的反斜線表示換行
[root@localhost ~]# sed -n '/^root/'p /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# sed -n '/^root/ c\ "admin"' /etc/passwd
"admin"
[root@localhost ~]# sed -n '1 c\ jack' /etc/passwd #將文件的第一行替換為字元串jack
jack
[root@localhost ~]#
[root@localhost ~]# sed -n '1,2'p /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@localhost ~]# sed -n '1,2 c\ admin' /etc/passwd #將第一行到第二行替換為字元串admin
adminp
[root@localhost ~]#
#####################3
替換命令: 用替換模式替換指定模式
[address,[address]] s/ pattern-to-find / replacement-pattern/ [g p w n] #註意: n選項將會使p選項無效
發現模式 替換模式
g: 預設只替換第一次出現的模式,使用g表示全局替換
p: 預設將所有被替換行寫入標準輸出,加p選項將使-n選項無效
w: 文件名,使用此選項將輸出重定向到一個文件
#--------------------------------------
[root@localhost ~]# sed -n 's/root/ROOT/'p /etc/passwd
ROOT:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/ROOT:/sbin/nologin
dockerROOT:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
[root@localhost ~]#
[root@localhost ~]# sed -n 's/root/ROOT/g'p /etc/passwd
ROOT:x:0:0:ROOT:/ROOT:/bin/bash
operator:x:11:0:operator:/ROOT:/sbin/nologin
dockerROOT:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
[root@localhost ~]#
[root@localhost shells]# sed -n 's/root/ROOT/w file.txt' /etc/passwd #替換一次,保存文件
[root@localhost shells]# ls
file.txt
[root@localhost shells]# more file.txt
ROOT:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/ROOT:/sbin/nologin
dockerROOT:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
[root@localhost shells]#
[root@localhost shells]# sed -n 's/root/ROOT/g w file.txt' /etc/passwd #全局替換
[root@localhost shells]# more file.txt
ROOT:x:0:0:ROOT:/ROOT:/bin/bash
operator:x:11:0:operator:/ROOT:/sbin/nologin
dockerROOT:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
[root@localhost shells]#
[root@localhost shells]# sed -n 's/root/ROOT/g p w file.txt' /etc/passwd #p屏幕顯示結果;w file.txt保存為文件;g表示全局匹配
ROOT:x:0:0:ROOT:/ROOT:/bin/bash
operator:x:11:0:operator:/ROOT:/sbin/nologin
dockerROOT:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
[root@localhost shells]# ls
file.txt
[root@localhost shells]# more file.txt
ROOT:x:0:0:ROOT:/ROOT:/bin/bash
operator:x:11:0:operator:/ROOT:/sbin/nologin
dockerROOT:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
[root@localhost shells]#
#####################################
sed -n 's/pattern/replacement-pattern-string &/p'
#在指定的字元串前插入內容:
&:保存發現模式以便重新調用它,然後把發現模式內容放在替換字元串後面
案例一: 在root字元串前插入"--ADMINISTRATOR--"
[root@localhost shells]# sed -n 's/root/"--ADMINISTRATOR--" &/p' /etc/passwd
"--ADMINISTRATOR--" root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/"--ADMINISTRATOR--" root:/sbin/nologin
docker"--ADMINISTRATOR--" root:x:988:982:Docker User:/var/lib/docker:/sbin/nologin
[root@localhost shells]#
[root@localhost shells]#
##############################################3
sed -n '[address[,address]] w filename' pathname #將指定的行保存到filename
案例:
[root@localhost shells]# ls
[root@localhost shells]# sed -n '1,2 w file.txt' /etc/passwd
[root@localhost shells]# ls
file.txt
[root@localhost shells]# more file.txt
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@localhost shells]#
##################################################
address r filename #從一個文件讀取文件內容到另一個文件中
案例:
[root@localhost shells]# sed '/root/ r jack.txt' /etc/passwd | more ##將jack.txt文件讀取存放到/root/模式後
root:x:0:0:root:/root:/bin/bash
####
jack
####
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
##################################################
[root@localhost ~]# more ab
Mr Willis
[root@localhost ~]# sed 's/Mr/ & Jack/g' ab
Mr Jack Willis
[root@localhost ~]# sed 's/Mr/ & Jack/p' ab #將會列印所有文件內容,
Mr Jack Willis
Mr Jack Willis
[root@localhost ~]# sed -n 's/Mr/ & Jack/p' ab
Mr Jack Willis
[root@localhost ~]#
[root@localhost ~]# echo "file" | sed 's/$/.doc/g' #添加文件尾碼
file.doc
[root@localhost ~]#
@@@@@@@@@@@@@@@@
1. sed 's///g'
2. sed 'address[,address] w filename'
3. sed 'address[,address] r filename'
4. sed -n 's/pattern/replacement-pattern-string &/p'
5. a\,可以將指定文本一行或多行附加到指定模式位置;"a\"中的反斜線表示換行
6. i\,可以將指定文本一行或多行插入到指定模式位置;"a\"中的反斜線表示換行
7. c\,將指定模式匹配的行替換;"c\"中的反斜線表示換行
8. d\,將指定模式匹配的行刪除;"d\"中的反斜線表示換行
9. sed -n '1,$ l' #l將顯示所有控制字元,很少用
@@@@@@@@@@@@@@@@
####
awk
####
一.條件判斷語句(if)
if(表達式) #if ( Variable in Array )
語句1
else
語句2
格式中"語句1"可以是多個語句,如果你為了方便Unix awk判斷也方便你自已閱讀,你最好將多個語句用{}括起來。Unix awk分枝結構允許嵌套,其格式為:
if(表達式)
{語句1}
else if(表達式)
{語句2}
else
{語句3}
[chengmo@localhost nginx]# awk 'BEGIN{
test=100;
if(test>90)
{
print "very good";
}
else if(test>60)
{
print "good";
}
else
{
print "no pass";
}
}'
very good
每條命令語句後面可以用“;”號結尾。
#------------------------------------------
二.迴圈語句(while,for,do)
1.while語句
格式:
while(表達式)
{語句}
例子:
[chengmo@localhost nginx]# awk 'BEGIN{
test=100;
total=0;
while(i<=test)
{
total+=i;
i++;
}
print total;
}'
5050
#------------------------------------------
2.for 迴圈
for迴圈有兩種格式:
格式1:
for(變數 in 數組)
{語句}
例子:
[chengmo@localhost nginx]# awk 'BEGIN{
for(k in ENVIRON)
{
print k"="ENVIRON[k];
}
}'
AWKPATH=.:/usr/share/awk
OLDPWD=/home/web97
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
LANG=zh_CN.GB2312
。。。。。。
說明:ENVIRON 是awk常量,是子典型數組。
格式2:
for(變數;條件;表達式)
{語句}
例子:
[chengmo@localhost nginx]# awk 'BEGIN{
total=0;
for(i=0;i<=100;i++)
{
total+=i;
}
print total;
}'
5050
#------------------------------------------
3.do迴圈
格式:
do
{語句}while(條件)
例子:
[chengmo@localhost nginx]# awk 'BEGIN{
total=0;
i=0;
do
{
total+=i;
i++;
}while(i<=100)
print total;
}'
5050
以上為awk流程式控制制語句,從語法上面大家可以看到,與c語言是一樣的。有了這些語句,其實很多shell程式都可以交給awk,而且性能是非常快的。
break 當 break 語句用於 while 或 for 語句時,導致退出程式迴圈。
continue 當 continue 語句用於 while 或 for 語句時,使程式迴圈移動到下一個迭代。
next 能能夠導致讀入下一個輸入行,並返回到腳本的頂部。這可以避免對當前輸入行執行其他的操作過程。
exit 語句使主輸入迴圈退出並將控制轉移到END,如果END存在的話。如果沒有定義END規則,或在END中應用exit語句,則終止腳本的執行。
三、性能比較
[chengmo@localhost nginx]# time (awk 'BEGIN{ total=0;for(i=0;i<=10000;i++){total+=i;}print total;}')
50005000
real 0m0.003s
user 0m0.003s
sys 0m0.000s
[chengmo@localhost nginx]# time(total=0;for i in $(seq 10000);do total=$(($total+i));done;echo $total;)
50005000
real 0m0.141s
user 0m0.125s
sys 0m0.008s
實現相同功能,可以看到awk實現的性能是shell的50倍!