字符串處理
計(jì)算字符串長度
方法1:${#變量}
方法2:expr length "$變量" (如果內(nèi)容有空格音羞,則必須加上" ")獲取字符索引的位置
expr index "$變量" 字符
例:expr index "$string" str('str'在string中的索引位置仙逻,str拆分成3個(gè)字符,返回找到第一個(gè)字符的位置)獲取匹配子串的長度
expr match "$變量" 子串(必須要從頭開始匹配,否則會(huì)返回0)抽取字符串中的子串
方法1:
${變量:position}索引從0開始
${變量:position:length}
${變量: -position:length}或${變量:(-position):length}索引從-1開始
方法2:
expr substr "$變量" position length 索引從1開始需求描述:
變量string="Bigdata process framework is Hadoop,Hadoop is an open source project",執(zhí)行腳本后基公,打印輸出string字符串變量,并給出用戶以下選項(xiàng):
- 打印string長度
- 刪除字符串中所有的Hadoop
- 替換第一個(gè)Hadoop為Mapreduce
- 替換全部Hadoop為Mapreduce
用戶輸入數(shù)字1|2|3|4骗随,可以執(zhí)行對(duì)應(yīng)項(xiàng)的功能;輸入q|Q則退出交互模式
1 #!/bin/bash
2 #
3
4 function print_tips
5 {
6 echo "********************************"
7 echo "(1) 打印string長度"
8 echo "(2) 刪除字符串中所有的Hadoop"
9 echo "(3) 替換第一個(gè)Hadoop為Mapreduce"
10 echo "(4) 替換全部Hadoop為Mapreduce"
11 echo "用戶輸入數(shù)字1|2|3|4赴叹,可以執(zhí)行對(duì)應(yīng)項(xiàng)的功能鸿染;輸入q|Q則退出交互模式"
12 echo "********************************"
13 }
14
15 function len_of_string
16 {
17 echo "string長度:${#string}"
18 }
19
20 function delete_all_Hadoop
21 {
22 echo "${string//Hadoop/}"
23 }
24
25 function replace_first_Hadoop
26 {
27 echo "${string/Hadoop/Mapreduce}"
28 }
29
30 function replace_all_Hadoop
31 {
32 echo "${string//Hadoop/Mapreduce}"
33 }
34
35 string="Bigdata process framework is Hadoop,Hadoop is an open source project"
36
37 while true
38 do
39 echo "【string:$string】"
40 print_tips
41 read -p "please input your choice [1|2|3|4|Q|q]:" choice
42 case $choice in
43 1)
44 len_of_string
45 ;;
46 2)
47 delete_all_Hadoop
48 ;;
49 3)
50 replace_first_Hadoop
51 ;;
52 4)
53 replace_all_Hadoop
54 ;;
55 Q|q)
56 exit
57 ;;
58 *)
59 echo "請(qǐng)按提示輸入正確的指令"
60 esac
61 done
命令替換
方法1:`command`
方法2:$(command)
- 獲取系統(tǒng)的所用用戶并輸出
1 #!/bin/bash
2 #
3
4 index=1
5
6 for user in `cat /etc/passwd | cut -d ":" -f 1`
7 do
8 echo "user${index}:${user}"
9 index=$(($index + 1))
10 done
有類型變量
- declare / typeset
bash數(shù)學(xué)運(yùn)算expr
提示用戶輸入一個(gè)正整數(shù)num,然后計(jì)算1+2+3+....+num的值乞巧,必須對(duì)num是否為正整數(shù)做一個(gè)判斷涨椒,不符合當(dāng)允許重新輸入。
1 #!/bin/bash
2 #
3
4 while true
5 do
6 read -p '請(qǐng)輸入一個(gè)正整數(shù):' num
7 expr $num + 1 &> /dev/null
8 if [ $? == 0 ];then
9 if [ `expr $num \> 0` == 1 ]; then
10 for ((i=1;i<=$num;i++))
11 do
12 sum=`expr $sum + $i`
13 done
14 echo "1+2+...+$num=$sum"
15 exit
16 else
17 echo "輸入的不是正整數(shù)"
18 fi
19 else
20 echo "輸入格式錯(cuò)誤!2隙C饣!"
21 fi
22 continue
23 done
bc
bash內(nèi)建運(yùn)算器囤热,支持浮點(diǎn)數(shù)運(yùn)算
- 輸入bc 直接進(jìn)入交互模式
- 傳參 echo "scale=3;8/3"|bc
函數(shù)
- 函數(shù)的定義
//第一種
function_name()
{
//todo
}
//第二種
function function_name
{
//todo
}
- 向函數(shù)傳遞參數(shù)
函數(shù)傳參和腳本腳本傳參類似猎提,都是使用2.....
寫一個(gè)腳本,該腳本可以實(shí)現(xiàn)計(jì)算器的功能赢乓,可以進(jìn)行四則運(yùn)算
1 #!/bin/bash
2 #
3
4 function calculator
5 {
6 case $2 in
7 +)
8 echo "$1+$3=`expr $1 + $3`"
9 ;;
10 -)
11 echo "$1-$3=`expr $1 - $3`"
12 ;;
13 \*)
14 echo "$1*$3=`expr $1 \* $3`"
15 ;;
16 /)
17 echo "$1/$3=`expr $1 / $3`"
18 ;;
19 esac
20 }
21
22 calculator $1 $2 $3
todo:*號(hào)不能作為參數(shù)傳遞
- 函數(shù)的返回值
1、return
只能返回0-255的整數(shù)石窑,通常用來表示狀態(tài)
function_name && echo "ok" || echo "faile"
返回值為0則表示成功
2牌芋、echo
可以返回任何字符串結(jié)果
嚴(yán)格上不能算返回值,可用 ``來獲取echo的值 - 全局變量和局部變量
函數(shù)內(nèi)定義的變量默認(rèn)是全局變量松逊,local修飾則為局部變量 - 函數(shù)庫
定義庫函數(shù)文件base_function.lib
function add
{
echo "`expr $1 + $2`"
}
function reduce
{
echo "`expr $1 - $2`"
}
function mul
{
echo "`expr $1 \* $2`"
}
function div
{
echo "`expr $1 / $2`"
}
function sys_load
{
echo "Memory Info"
echo
free -m
echo
echo "Disk Usage"
echo
df -h
echo
}
. bash_function.lib(加點(diǎn)引用)躺屁,shell中取絕對(duì)路徑
可以直接使用庫函數(shù) :add 3 4
find 命令
語法格式:find [路徑] [選項(xiàng)] [操作]
選項(xiàng)
- -name,-iname(忽略大小寫))
find /etc -name '*conf'
- -user,-group)
- -type
find . -type f
f 文件
d 目錄
l 鏈接文件
... - -size)
-n 大小大于n的文件
+n 大小小于n的文件
查找/etc目錄下小于1000字節(jié)的文件:find /etc -size -1000c
查找/etc目錄下大于1M的文件:find /etc -size +1M
- -mtime,mmin)
-n n(天,分鐘)以內(nèi)修改的文件
+n n(天,分鐘)以外修改的文件 - -mindepth n(表示從n級(jí)子目錄開始搜索经宏,命令緊接目錄)
find /etc -mindepth 3
- -maxdepth n(表示最多搜索到n級(jí)子目錄)
命令
- -print(默認(rèn)))
- -exec(對(duì)搜索到的文件執(zhí)行特定的操作))
-exec 'command' {} \
將/var/log/目錄下以log結(jié)尾的文件犀暑,且更改時(shí)間在7天以上的復(fù)制到/root/conf/目錄下
find /var/log/ -type -f -name '*log' -mtime +7 -exec cp {} /root/conf/ \;
locate命令
在數(shù)據(jù)庫文件中查找
更新數(shù)據(jù)庫updatedb
whereis命令
- -b 返回二進(jìn)制執(zhí)行文件
- -m 返回幫助文檔文件
- -s 返回源代碼文件
which命令
- -b 只返回二進(jìn)制程序文件
grep命令
語法格式:
grep [option] [pattern] [file1,file2....]
command | grep [option] [pattern]
option
- -v 不顯示匹配行信息
- -i 忽略大小寫
- -n 顯示行號(hào)
- -r 遞歸搜索
- -E 支持?jǐn)U展正則表達(dá)式
- -F 按照字符串字面意思匹配
- -c 只輸出匹配行的數(shù)量
- -w 匹配整詞
- -x 匹配整行
- -l 只列出匹配的文件名,不顯示具體內(nèi)容
sed命令
語法格式:
sedout | sed [option] "pattern command"
sed [option] "pattern command" file
option
- -n 只打印模式匹配行
- -e 直接在命令行進(jìn)行sed編輯烁兰,默認(rèn)選項(xiàng)耐亏,當(dāng)有兩個(gè)或以上的命令時(shí),每個(gè)命令前都要加-e
- -f 編輯動(dòng)作保存在文件中沪斟,指定文件執(zhí)行
- -r 支持?jǐn)U展正則表達(dá)式
- -i 直接修改文件內(nèi)容
pattern 匹配模式
- 10command:匹配到第10行
- 10,20command:匹配10到20行
- 10,+5command:匹配10到15行
sed -n '10,+5p' test.sec
- /pattern/command:匹配到pattern的行广辰,支持基礎(chǔ)正則
sed -n '/^root/p' /etc/passwd
- /pattern1/,/pattern2/command
- /pattern1/,10command
- 10,/pattern1/command
匹配范圍:如果找不到匹配的行會(huì)打印所有,數(shù)字結(jié)尾則打印開始匹配的一行
sed -n '/^root/,/^uucp/p' /etc/passwd
command 編輯命令
打印
- p 打印
增加
- a 行后追加
sed -i '/\/bin\/bash/a This is a user which can login' passwd
- i 行前追加
- r 外部文件讀入主之,行后追加
sed -i '/^kang/r ./insert.txt' passwd
- w 匹配行寫入外部文件
sed -i '/\/sbin\/nologin/w ./nologin.txt' passwd
刪除
- d 刪除
sed -i '/^root/,/^uucp/d' passwd
修改
- s/old/new 將行內(nèi)第1個(gè)old替換為new
- s/old/new/2 將行內(nèi)第2個(gè)old替換為new
- s/old/new/g 將行內(nèi)全部的old替換為new
- s/old/new/2g 將行內(nèi)第2個(gè)及以后old替換為new
- s/old/new/ig 將行內(nèi)old全部替換為new择吊,忽略大小寫
sed -i 's/This is a user which can login/yes I am/g' passwd
- 反向引用
&:&只表示匹配到的完整字符串
sed -i 's/he..o/\<&\>/g' test.txt
\1:可以取匹配字符串的()括起來的部分
sed -i 's/\(he.\).o/\1qqq/g' test.txt
案例1:輸入mysql的my.cnf文件,根據(jù)段名輸出該段包含項(xiàng)的數(shù)量
1 mysqld 4
2 mysqld_safa 2
1 #!/bin/bash
2 #
3
4 MYSQLCONF_NAME=/root/linux_test/test/my.cnf
5
6 function get_all_segments
7 {
8 echo "`sed -n '/\[.*\]/p' $MYSQLCONF_NAME|sed -e 's/\[//g' -e 's/\]//g' `"
9 }
10
11 function count_items_in_segment
12 {
13 sum=`sed -n '/\['$1'\]/,/\[.*\]/p' $MYSQLCONF_NAME|grep -v '\[.*\]'|grep -v '^$'|grep -v '^#'|wc -l`
14 echo "$sum"
15 }
16
17 index=0
18 for item in `get_all_segments`
19 do
20 index=`expr $index + 1`
21 echo "$index:$item `count_items_in_segment $item`"
22 done
案例二:刪除配置文件中的所有注釋行和空行
sed -i '/[:blank:]*#/d' nginx.conf
案例三:在配置文件中所有不以#開頭的行前面添加*符號(hào)
sed -i 's/^[^#]/\*&/g nginx.conf'
awk命令
語法格式:
awk -f 文件名
awk 'BEGIN{}pattern{commands}END{}' file_name
standard output | awk 'BEGIN{}pattern{commands} END{}'
內(nèi)置變量
- $0 整行內(nèi)容
-
n 當(dāng)前行的第1-n個(gè)字段
- NF 當(dāng)前行的字段個(gè)數(shù)槽奕,即有多少列
- NR 當(dāng)前行的行號(hào)几睛,從1開始計(jì)數(shù)
- FNR 多文件處理是,每個(gè)文件行號(hào)單獨(dú)計(jì)數(shù)粤攒,從1開始
- FS 輸入字段分隔符所森,不指定默認(rèn)以空格或tab鍵分割
- RS 輸入行分隔符,默認(rèn)回車換行
- OFS 輸出字段分隔符夯接,默認(rèn)為空格
- ORS 輸出行分隔符必峰,默認(rèn)回車換行
- FILENAME 當(dāng)前輸入的文件名字
- ARGC 命令行參數(shù)個(gè)數(shù)
- ARGV 命令行參數(shù)數(shù)組
printf
格式符 | 含義 |
---|---|
%s | 打印字符串 |
%d | 打印十進(jìn)制數(shù) |
%f | 打印浮點(diǎn)數(shù) |
%x | 打印十六進(jìn)制數(shù) |
%o | 打印八進(jìn)制數(shù) |
%e | 打印數(shù)字的科學(xué)計(jì)數(shù)法 |
%c | 打印單個(gè)字符的ASCII碼 |
%s | 打印字符串 |
awk 'BEGIN{FS=":"} {printf "0.2%f\n",$3}' /etc/passwd
修飾符 | 含義 |
---|---|
- | 左對(duì)齊(默認(rèn)右對(duì)齊) |
# | 顯示8進(jìn)制在前面加0,顯示16進(jìn)制在前面加0x |
awk 'BEGIN{FS=":"} {printf "%#x\n",$3}' /etc/passwd
awk 'BEGIN{FS=":"} {printf "%-12d\n",$3}' /etc/passwd
pattern模式匹配
- 正則表達(dá)式匹配
匹配/etc/passwd文件行中含有root字符串的所有行
awk 'BEGIN{FS=":"}/root/{print $0}' /etc/passwd
匹配/etc/passwd文件行中以yarn開頭的所有行
awk 'BEGIN{FS=":"}/^yarn/{print $0} /etc/passwd'
- 關(guān)系運(yùn)算匹配(> < == >= != ~匹配正則 !~ )
匹配/etc/passwd文件行中第3個(gè)字段小于50的所有行
awk 'BEGIN{FS=":"}$3<50{print $0}' /etc/passwd
匹配/etc/passwd文件行中第7個(gè)字段等于/bin/bash的所有行
awk 'BEGIN{FS=":"}$7=="/bin/bash"{print $0}' /etc/passwd
匹配/etc/passwd文件行中第3個(gè)字段包含3個(gè)以上數(shù)字的所有行
當(dāng)出現(xiàn){x,y}次數(shù)匹配钻蹬,需加上--posix或--re-interval
awk --posix 'BEGIN{FS=":"} $3~/[0-9]{3,}/{print $0}' /etc/passwd
- 布爾運(yùn)算符(&& || !)
匹配/etc/passwd文件行中第1個(gè)字段包含hdfs或yarn的所有行
awk 'BEGIN{FS=":"}$1=="hdfs"||$1=="yarn"{print $0}' /etc/passwd
匹配/etc/passwd文件行中第3個(gè)字段和第4個(gè)字段同時(shí)包含3個(gè)以上數(shù)字并且的所有行
awk --re-interval 'BEGIN{FS=":"} $3~/[0-9]{3,}/&&$4~/[0-9]{3,}/{print $0}' /etc/passwd
條件表達(dá)式和循環(huán)表達(dá)式
awk 'BEGIN{FS=":"}{if($3>50) {print "$3>50",$3} else {print "$3<50",$3}}' /etc/passwd
三種循環(huán)(while/ do while/ for())
awk '{num=NF-1;for(i=2;i<=NF;i++){sum=sum+$i};AVG=sum/num;sum=0;print AVG}' ipAddress
字符串函數(shù)
函數(shù) | 功能 |
---|---|
length(str) | 計(jì)算長度 |
index(str1,str2) | 返回str1中查詢到的str2的位置 |
tolower(str) | 小寫轉(zhuǎn)換 |
toupper(str) | 大寫轉(zhuǎn)換 |
split(str,arr,fs) | 分割字符串吼蚁,并保存到arr中,返回?cái)?shù)量 |
match(str,RE) | 返回正則表達(dá)式匹配到的子串位置 |
substr(str,m,n) | 截取子串,從m開始截取n位 |
sub(RE,RepStr,str) | 替換查找到的第一個(gè)子串肝匆,返回替換的個(gè)數(shù) |
gsub(RE,RepStr,str) | 替換查找到的所有子串粒蜈,返回替換的個(gè)數(shù) |
以:為分隔符,返回/etc/passwd中每行的各個(gè)字段的長度
awk '{num=split($0,arr,":");for(i=1;i<=num;i++){printf "%d ",length(arr[i])};print ""}' /etc/passwd
[option]
- -v 定義或引用變量
awk -v a="$PATH" -v b="$JAVA_HOME" 'BEGIN{print a,b}'
- -f 指定awk命令文件
數(shù)組
- shell中的數(shù)組
arr=("dfdf" "wew" "eweedv")
打印元素,下標(biāo)從0開始:echo ${arr[0]}
打印元素個(gè)數(shù):echo ${#arr[@]}
echo ${#arr[*]}
給元素賦值:arr[1]="xxxx"
刪除元素旗国,元素下標(biāo)不變:unset arr[2]
unset arr
分片訪問:echo ${arr[@]:1:3}
元素內(nèi)容替換:第一個(gè)echo ${arr[*]/a/A}
全部echo ${arr//a/A}
數(shù)組的遍歷:for i in ${arr[@]} do xxx done
- awk中的數(shù)組
默認(rèn)為數(shù)字下標(biāo),從1開始
awk 'BEGIN{str="mike ammy jack tom";split(str,arr);for(i=1;i<=length(arr);i++){print arr[i]}}'
也可以字符串為下標(biāo),推薦使用
awk 'BEGIN{arr["var1"]="jack";arr["var2"]="mike";for(i in arr) print arr[i]}'
統(tǒng)計(jì)主機(jī)上所有Tcp連接狀態(tài)數(shù)枯怖,按照每個(gè)Tcp狀態(tài)分類
netstat -an | grep tcp | awk '{array[$6]++}END{for(i in array) print i,array[i]}'
計(jì)算橫向數(shù)據(jù)綜合,計(jì)算縱向數(shù)據(jù)總和
1 BEGIN{
2 printf "%-8s%-8s%-8s%-8s%-8s%-8s\n","name","A","B","C","D","AVG"
3 }
4 {
5 printf "%-8s",$1
6 sum=0;
7 avg=0;
8 for(i=2;i<=5;i++)
9 {
10 printf "%-8d",$i
11 sum=sum+$i
12 array[i]=array[i]+$i
13 };
14 avg=sum/NF
15 printf "%-8.2f\n",avg
16 }
17 END{
18 printf "%-8s%-8d%-8d%-8d%-8d\n","Total",array[2],array[3],array[4],array[5]
19 }