Linux命令行和Shell腳本編程(二)

一、Linux命令行

Linux命令行和Shell腳本編程(一)

二、Shell腳本編程

2.3 循環語句for

#格式1
for var in list
do
commands
done
#格式2
for (( variable assignment ; condition ; iteration process ))
#示例
for test in Alabama Alaska Arizona Arkansas California Colorado
for test in I don't know if this'll work    #error,I@dont know if thisll@work
for test in I don\'t know if "this'll" work
"
for test in Nevada New Hampshire New Mexico New York North Carolina    #error
for test in Nevada "New Hampshire" "New Mexico" "New York"

list="Alabama Alaska Arizona Arkansas Colorado"
list=$list" Connecticut"
for state in $list

for state in $(cat $file)
IFS=$'\n'
for state in $(cat $file)

for file in /home/rich/test/*

內部字段分隔符(IFS):

IFS環境變量定義了bash shell用作字段分隔符的一系列字符 默認是空格、製表符和換行符 

可以在shell腳本中臨時更改IFS環境變量的值來限制被bash shell當作字段分隔符的字符 

2.4 循環語句while

#格式1
while test command
do
other commands
done
#格式2
while [ condition ]
do
other commands
done

 while命令每次迭代時檢查測試條件,只要測試條件成立, while命令就會不停地循環執行定義好的命令 

2.5 循環語句until

#格式1
until test command
do
other commands
done
#格式2
until [ condition ]
do
other commands
done

 until命令每次迭代時檢查測試條件,只要測試條件不成立, until命令就會不停地循環執行定義好的命令

2.6 循環控制break,continue

break命令:退出循環
continue命令 :提前中止某次循環,但不會終止循環  

2.7 處理用戶輸入/輸出

命令行參數:

Shell提供位置參數在腳本中使用

$0是程序名, $1是第一個參數, $2是第二個參數,依次類推,直到第九個參數$9 

如果有超過9個參數,在使用時用花括號,如${10} 

特殊參數變量:

$#:表示腳本運行時命令行參數的個數,不包含文件名

${!#}:表示最後一個參數的值

$*:表示將命令行上所有參數當作一個字符串保存

$@:表示將命令行上提供的每一個參數當作獨立字符串來保存

移動變量:

shift命令表示將所有參數向左移動一個位置

適用於在不知道用戶傳多少參數時,只操作第一個參數,然後移動參數,繼續操作第一個參數 

shift n:表示將所有參數向左移動n個位置
接受用戶輸入:

read var
read -p "description" var
read –t 5 var #設置超時時間
read –n1 var #表示變量名只接受一個字符
read –s var #隱藏方式讀取 

處理輸出:

Linux用文件描述符(file descriptor)來標識每個文件對象。文件描述符是一個非負整數,可以唯一標識會話中打開的文件。每個進程一次最多可以有九個文件描述符。出於特殊目的, bash shell保留了前三個文件描述符(0、 1和2)

重定向錯誤:

如果只重定向錯誤消息,將文件描述符值放在重定向符號前,且不能出現空格

ls -al badfile 2> test4 #重定向錯誤
ls -al test test2 badtest 2> test6 1> test7 #重定向錯誤和正常輸出
ls -al test test2 badtest &> test7 #重定向錯誤和正常輸出到一個文件

command >&2 #將命令輸出指定到錯誤輸出
echo "and this should be stored in the file" >&2

exec 1> testout #永久重定向標準輸出到testout文件
exec 2> testerror #永久重定向標準錯誤到testerror文件
exec 0< testfile #永久重定向testfile爲標準輸入
exec 3> test13out #創建自己的輸出文件描述符
echo "and this should be stored in the file" >&3
exec 1>&3 #將標準輸出重定向到文件描述符3

exec 6<&0 #將標準輸入重定向到文件描述符6,相當於是保存下標準輸入重定向,之後再賦值回去
exec 0< testfile
exec 0<&6
exec 6>&- #關閉文件描述符

ls -al > /dev/null #阻止命令輸出
cat /dev/null > testfile

三、高級Shell腳本編程

3.1 函數

#格式1:
function name {
commands
}
#格式2:
name() {
commands
}

注意:花括號之前要有空格

#向函數傳遞參數
fun1 $val1 $val2

#傳遞命令行參數
function badfunc1 {
echo $[ $1 * $2 ]
}
value=$(badfunc1)    #error
value=$(func7 $1 $2)

return命令來退出函數並返回特定的退出狀態碼,保存在$?
echo可以返回函數的返回值
由於函數使用特殊參數環境變量作爲自己的參數值,因此它無法直接獲取腳本在命令行中的參數值。
 全局變量和局部變量:

Shell腳本中定義的變量都是全局變量,包括在函數中定義的變量,即函數內定義的變量,函數外也可以訪問並賦值

local  變量名:即使與全局變量同名,函數內部會使用局部變量

函數的作用域:
shell函數僅在定義它的shell會話內有效,而shell會創建一個新的shell並在其中運行腳本

#!/bin/bash
./myfuncs
result=$(addem 10 15)    #error
. ./myfuncs    #點操作符,是source的別名

3.2 grep

選項 描述
-c

只輸出匹配到的行數

-e

指定多個匹配模式

-E

支持擴展正則表達式

-i

忽略大小寫

-n

標出行號

-o

只輸出匹配到的部分

-r

遞歸查找

-v

輸入不符合條件的行 

#示例
grep [option] pattern file
grep -c "hello" file
grep -rn "hello"
grep -i "Hello" file
grep -v "hello" file
grep -o "hello" file
grep -e "hello" -e "cat" file
grep -n "hello" file*
grep -n "^hello" file
grep -n "hello$" file
grep -n "hello*" file
grep -n "hello." file
grep -n "hello[1,2]" file
grep -n "hello[^1,2]" file

3.3 awk

#awk格式
awk options command file

 

#awk命令示例
echo "test" | awk '{print "Hello World!"}'    #Hello World!
awk '{print $1}' data.txt#$0表示整行,$1表示第一列,$2表示第二列,$n表示第n列
awk -F: '{print $1}' /etc/passwd
echo "My name is Rich" | awk '{$4="Christine"; print $0}'
awk -F: -f script.gawk /etc/passwd    #{print $1, $2}

awk options 'BEGIN{} // {command1;command2} END{}' file    #//是正則表達式

awk 'BEGIN {print "Hello World!"}; {print $1}' data.txt
awk 'BEGIN {print "Hello World!"}; {print $1}; END {print "End of File"}' data.txt
awk 'BEGIN{FS=","} {print $1,$2,$3}' data1    #data1文件以,作爲分隔符
awk 'BEGIN{FS=","; OFS="-"} {print $1,$2,$3}' data1    #以,分隔符讀取,以-分隔符輸出

3.4 sed

#sed格式
sed options command file

#替換
echo "This is a test" | sed 's/test/big test/'
sed 's/dog/cat/' data1.txt
sed -e 's/brown/green/; s/dog/cat/' data1.txt
sed -f script1.sed data1.txt
sed 's/dog/cat/2' data1.txt
sed 's/dog/cat/g' data1.txt
sed -n 's/dog/cat/p' data1.txt #只輸出被替換的行,-n選項禁止sed編輯器輸出
sed 's/test/trial/w test.txt' data5.txt
sed 's!/bin/bash!/bin/csh!' /etc/passwd
sed '2s/dog/cat/' data1.txt
sed '2,3s/dog/cat/' data1.txt
sed '2,$s/dog/cat/' data1.txt #從第2行到最後一行
sed '/Lewis/s/bash/csh/' /etc/passwd
#刪除
sed 'd' data1.txt   
sed '3d' data1.txt
sed '2,3d' data1.txt 
sed '3,$d' data1.txt
sed '/number 1/d' data1.txt #將含有number 1的行刪除
#插入/附加
echo "Test Line 2" | sed 'i\Test Line 1' #插入文本出現在流文本前面
echo "Test Line 2" | sed 'a\Test Line 1' #附加文本出現在流文本後面
sed '3i\This is an inserted line.' data6.txt #在第三行插入
sed '3a\This is an appended line.' data6.txt #在第四行插入
sed '$a\This is an appended line.' data6.txt
#修改
sed '3c\This is a changed line of text.' data6.txt
sed '2,3c\This is a changed line of text.' data6.txt
sed '/number 3/c\This is a changed line of text.' data6.txt
#寫入文件
sed '1,2w test.txt' data6.txt
sed -n '/Lewis/w Lewis.txt' /etc/passwd

3.5 正則表達式

基礎正則表達式:
^ :只匹配行首
$ :只匹配行尾
.  :匹配除換行符之外的任意單個字符
* :匹配0次或多次 
[ch] :只匹配字符組中出現的字符,支持[0-9] ,[c-h] 
[^ch] :匹配除字符組中字符的其他字符

擴展正則表達式:

? :匹配0次或1次
+ :匹配1次或多次
{m}:匹配m次
{m, n}:匹配m到n次
| :或,匹配多個模式
() :括號內的字符串被認爲是一個整體
 

#正則表達式之grep
grep -E "hello?" file
grep -E "hello+" file
grep -E "hello{2}" file
grep -E "hello{2,3}" file
grep -E "hello?|hi" file
grep -E "he(llo)?" file

#正則表達式之sed
echo "The books are expensive" | sed -n '/book/p'
echo "Books are great" | sed -n '/^Book/p'
echo "This ^ is a test" | sed -n '/s ^/p'
echo "This is a good book" | sed -n '/book$/p'
sed -n '/^this is a test$/p' data4
sed '/^$/d' data5
sed -n '/.at/p' data6 #可以匹配cat, at
sed -n '/[ch]at/p' data6
sed -n '/[^ch]at/p' data6
sed -n '/^[0-9][0-9][0-9]$/p' data8
echo "abc" | sed -n '/[[:alpha:]]/p'
echo "ik" | sed -n '/ie*k/p'
echo "ieeek" | sed -n '/ie*k/p'
echo "bat" | sed -n '/b[ae]*t/p'
echo "bet" | sed -n '/b[ae]*t/p'

#正則表達式之awk
echo "bet" | awk '/be?t/{print $0}'
echo "beet" | awk '/be?t/{print $0}' #no output
echo "bat" | awk '/b[ae]?t/{print $0}'
echo "bet" | awk '/be+t/{print $0}'
echo "bt" | awk '/be+t/{print $0}' #no output
echo "bat" | awk '/b[ae]+t/{print $0}'
echo "bet" | awk '/be{1}t/{print $0}'
echo "beet" | awk '/be{1,2}t/{print $0}'
echo "bat" | awk '/b[ae]{1,2}t/{print $0}'
echo "The cat is asleep" | awk '/cat|dog/{print $0}'
echo "He has a hat." | awk '/[ch]at|dog/{print $0}'
echo "Saturday" | awk '/Sat(urday)?/{print $0}'

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章