shell笔记

echo  用法
echo加不加双引号都是一样的效果


#!/bin/bash
#this script display the date and who's login on
echo "the time and date are:"
date
echo let's see who's login the system:
who


#!/bin/bash
#this script display the date and who's login on
echo -n "the time and date are:"
date
echo -n "let's see who's login the system:"
who


变量赋值


#!/bin/bash
#testing variables
days=10
guest="kaite"
echo "$guest checked in $days ago"
days=5
guest="jessica"
echo "$guest checked in $days ago"

$  echo "the cost of the item is $15"



#!/bin/bash
varue1=10
varue2=$varue1
echo "the costing is $varue2"


#!/bin/bash
varue1=10
varue2=$varue1
echo "the costing is $varue1"


#!/bin/bash
varue1=10
varue2=varue1
echo "the costing is $varue2"

the costing is varue1


反引号:

$ testing=`date`
$ echo $testing
2017年05月11日 周四 下午 4:17:06


#!/bin/bash
#use the backtick character
testing=`date`
echo "the date and time is $testing "


$ sh a.sh
the date and time is 2017年05月11日 周四 下午  4:25:13


#!/bin/bash
#copy the /usr/bin directory listing to log file
today=`date +%y%m%d`           -- +号要紧挨着后面
ls /usr/bin -al > log.$today   --在当前目录下产生个文件


输出重定向

$ command > outpoutfile
$ date > b.file
$ ls -l > b.file
$ date > test6  -----会自动创建文件

追加

$ who >> test6



输入重定向

$ wc < test6
 1  4 41      ----文本行数,词数,字节数

$ wc << EOF
text string 1
test string 2
test string 3
EOF
 3  9 42

管道 :某个命令的输出作为另一个命令的输入
$ cat test6 > rpm.list
$ ls < rpm.list
a.sh  b.file  rpm.list  test6


数学运算

1expr  基本不能用

$ expr 1 + 5    -------加好两边要分开,等于号两边要紧挨着 这和python不一样
6

$ expr 2 * 5
expr: 语法错误
$ expr 2 \* 5   --------反斜杠可以识别shell不能识别的错误
10

2、方括号

使用方括号  ---$+[]和赋值加echo结合构成运算

$ var1=$[1+5]
$ echo $var
6

var2=$[$var2+3]
echo $var2
13


var1=10
var2=20
var3=30
var4=$[$var2*(var1+var3)]
echo "the resoult is" $var4


只支持整数运算

#!/bin/bash
var1=30
var2=20
var3=$[$var1 /$var2]
echo $var3
$ sh a.sh
1

bc计算器

命令hang输入bc
#!/bin/bash
variable=`echo "options;expression" | bc`

#!/bin/bash
var1=`echo "scale=4;3.14 / 5 |bc"`
echo the answer is $var1


#!/bin/bash
#testing the exist status
var1=10
var2=30
var3=$[$var1+$var2]
echo the answer is $var3
exit 5

echo $?


退出状态码最大值是255
#!/bin/bash
#testing the exit status
var1=10
var2=30
var3=$[$var1+$var2]
exit $var3

$ echo $?
40

#!/bin/bash
#testing the exit status
var1=10
var2=30
var3=$[$var1*$var2]
exit $var3

$ echo $?
44



结构化命令
if-then

if command

then
    commands
fi


#!/bin/bash
if date

then
    echo "it works"

fi


#!/bin/bash
#testing multiple commands in the then section
testuser=rich
if grep $testuer /etc/passwd
then
    echo the bash files for user $testuser are:
    ls -a /home/$testuser/ .b*
fi





if-then-else

if commands
then
    commands
else
    commands
fi


if-then-elif

test
test condtion

if []     ----------if [ 数字 ] ---注意格式,要分开。
then
    commands


作用:1.数字比较  2、字符串比较  3、文件比较


#!/bin/bash
#using numeric test comparisons
var1=10
var2=20
if [ $var1 -gt 5 ]
then
    echo "$var1 is greater then 5"
fi


#!/bin/bash
#using numeric test comparisons
var1=10
var2=20
if [ $var1 -eq $var2 ]
then
    echo "$var1 is eq $var2"

else    echo "$var1 is not eq $var2"
fi



#!/bin/bash
#testing string equality
testuser=rich
if [ $USER -eq $testuer ]
then
    echo"the string is eqiality"



大于号当成了输出重定向

#!/bin/bash
#mid-using string comparitions
var11=basuely
var2=rich
if [ $var11 > $var12 ]
then
    echo "$var11 is greater $var12"
else
    echo "$var11 is less then $var12"

fi


$ ls -l rich
-rw-r--r-- 1 Administrator None 0 五月 13 16:30 rich


#!/bin/bash
#mid-using string comparitions
var11=basuely
var2=rich
if [ $var11 \> $var12 ]
then
    echo "$var11 is greater $var12"
else
    echo "$var11 is less then $var12"

fi


-n -z检验是否含有数据

#!/bin/bash
var1=testing
var2=''
if [ -n $var1 ]
then
    echo "the testing is not null"
else
    echo "the tesing is null"
fi


#!/bin/bash
var1=testing
var2=''
if [ -z $var1 ]
then
    echo "the testing is not null"
else
    echo "the tesing is null"
fi



文件比较

检查目录

#!/bin/bash
if [ -d $usr ]
then
    echo "the dictionary is exists"
    cd $usr
    ls -a
else
    echo "the dictionary is not exists"
fi




判断文件是否为空


#!/bin/bash
#testing the file exists and if have data
file=testing15
touch $file
if [ -s $file ]
then
    echo "the $file is not empty and have data"
else
    echo "the $file is empoty"
fi

date > $file
if [ -s $file ]
then
    echo "the $file is exist and have data"
else 
    echo "the file is not exist"
fi



判断文件是否可写

#!/bin/
#test the file if or not writerable
logfile=$HOME/testing15
touch $logfile
chmod u-w $logfile
time=`date +%y%m%d-%M%H`
if [ -w $logfile ]
then
    echo "the program is running in $time" > $logfile
    echo "the first testing is succeed"
else
    echo "the first testing is fail"
fi

chmod u+w $logfile
if [ -w $logfile ]
then 
    echo "the program is running in $time" > $logfile
    echo "the second testing is succeed"
else
    echo "the second testing is fail"
fi


检查属组

#!/bin/bash
#testing the file'group
if [ -g $home/testing ]
then
    echo "you have the group"
else 
    echo "you not have the group"
fi



比较文件如期

#!/bin/bash
if [ -test18 -nt test19 ]
then
    echo "the test18 is newer then test19"
else
    echo "the test9 is newer then test18"
fi





#!/bin/bash
if [ -test18 -nt test19 ]
then
    echo "the test18 is newer then test19"
else
    echo "the test19 is newer then test18"
fi

if [ -test18 -ot test20 ]
then
    echo "the test18 is ower then test20"
else
    echo "the test20 is ower then test18"
fi





布尔运算符

#!/bin/bash
if [ -d $home ] && [ -w $home/testing ]
then
    echo "the file exist and can write"
else
    "can not writing"
fi




使用双尖括号

#!/bin/bash
var1=10
if (( $var1 ** 2 > 90 ))
then
    (( var2=$var1 ** 2 ))
    echo "the square of $var1 is $var2"
fi




双方括号,匹配模式。

#!/bin/bash
if [[ $user == r* ]]
then 
    echo "hello $user"
else
    echo "no have user"
fi


case用法

#!/bin/bash
#using the case
case $user in
fich | barbara)
    echo "hello "
    echo "please enjoy it";;
testing)
    echo "hello testing";;
jessica)
    echo "hello jessica";;
esac



for循环

#!/bin/bash
for test in china american canda
do
    echo "the state in $test"
done


#!/bin/bash
for test in one tow three fore
do
    echo "we will go $test"
done



#!/bin/bash
for test in one tow three four "file +teen" "green blue"
do
    echo "we will go $test"
done



通过遍历来打印数据

#!/bin/bash
list="alabama alaska arizona"
list=$list" china"
for test in $list
do 
    echo "have you been to $test"
done



从命令中读取--反引号使用

#!/bin/bash
file=status
for statu in `cat $file`
do
    echo "welcome to $statu"
done


china  ues
american
cnada


$ sh a.sh
welcome to china
welcome to ues
welcome to american
welcome to cnada


更改字段分隔符

#!/bin/bash
file=status
IFS=$'\n'
for statu in `cat $file`
do
    echo "welcome to $statu"
done


$ sh a.sh
welcome to china  ues
welcome to american
welcome to cnada




用通配符读取目录

#!/bin/bash
for file in /etc/*
do
if [ -d "$file" ]
then
    echo "$file is a dictionary"
elif [ -f $file ]
then
    echo "$file is a file"

fi
done



C语言的for命令

#!/bin/bash
for (( i=1; i<=10; i++ ))
do
    echo "the next number is $i"
done



使用多个变量

#!/bin/bash
for (( a=1, b=10; a<=10; a++,b-- ))
do
    echo "the next number is $a-$b"
done



#!/bin/bash
for (( a=1, b=10; a<=10,b<=20; a++,b++ ))
do
    echo "the next number is $a-$b"
done



while基本格式

自身减一

#!/bin/bash
var1=10
while [ $var1 -gt 0 ]  ---测试如果大于0
do
    echo $var1
    var1=$[ $var1 - 1 ]
done


使用多个测试命令

#!/bin/bash
var1=10
while   echo $var1
        [ $var1 -gt 0 ]
do
    echo "this is inside the loop"
    var1=$[ $var1 - 1 ]           -----一定要带$号,等于号一定要紧挨着
done



until 命令

#!/bin/bash
var1=100
until [ $var1 -eq 0 ]
do
    echo $var1
    var1=$[ $var1-25 ]
done




until多个测试命令

#!/bin/bash
var1=100
until echo $var1
    [ $var1 -eq 0 ]
do
    echo "inside the loop $var1"
    var1=$[ $var1 -25 ]
done



嵌套循环

#!/bin/bash
for (( a=1; a<=3; a++ ))
do
    echo "string $a"
    for (( b=1; b<=3; b++ ))
    do
        echo "the inside is $b"
    done
done



只要是中括号都得带 $ 这就是规定

#!/bin/bash
#!/bin/bash
var1=5
while [ $var1 -ge 0 ]
do
    echo "ouiter value is $var1"
    for (( var2=1; var2<=3; var2++ ))
    do
        var3=$[ $var1 * $var2 ]
        echo "$var1 * $var2 = $var3"
    done
var1=$[ $var1-1 ] 
done




跳出循环

#!/bin/bash
#!/bin/bash
for var1 in 1 2 3 4 5 6 7 8 
do
    if [ $var1 -eq 5 ]
    then
        break
    fi
echo "the literation is $var1"
done
echo "the loop is complete"



跳出单个循环

#!/bin/bash
#!/bin/bash
var1=1
while [ $var1 -le 10 ]
do
    if [ $var1 -eq 5 ]        
    then
        break
    fi
echo "the literation is $var1"

var1=$[$var1 + 1 ]
done





跳出内部循环--先命令,再条件

#!/bin/bash
for (( a=1; a<=5; a++ ))
do
    echo "outer $a"
    for (( b=1; b<=100; b++ ))
    do
        echo "inter $b"
        if [ $b -eq 3 ]
        then
            break
        fi
        
    done
done



跳出外部循环


#!/bin/bash
for (( a=1; a<=5; a++ ))
do
    echo "outer $a"
    for (( b=1; b<=100; b++ ))
    do
        echo "inter $b"
        if [ $b -eq 3 ]
        then
            break 2
        fi
        
    done
done



continue命令

#!/bin/bash
for (( a=1; a<=15; a++ ))
do
    if [ $a -gt 5 ] && [ $a -lt 10 ]
    then
        continue
    fi
    echo "inter loop $a"
done




while+continue 出问题 必须用  sh a.sh | more 才会停止

#!/bin/bash
var1=0
while echo "the literation $var1"
    [ $var1 -lt 15 ]
do
    if [ $var1 -gt 5 ]&& [ $var1 -lt 10 ]
    then
        continue
    fi

var1=$[$var1+1]
done

$ sh a.sh | more





用continue跳出指定内部循环
#!/bin/bash
for (( a=1; a<=5; a++ ))
do
    echo "outer loop $a"
    for (( b=1; b<=3; b++ ))
    do
        if [ $a -gt 3 ]&&[ $a -lt 5 ]
        then
            continue 2
        fi
        var3=$[ $a*$b ]
        echo "the resoult $var3=$a*$b"    
    done
done




处理循环的输出

#!/bin/bash
for file in /etc/*
do
    if [ -d "$file" ]
    then
        echo "the $file is a dictionary"
    else
        echo "the $file is a file"
    fi
done > output.txt



#!/bin/bash
for(( a=1; a<=8; a++ ))
do
    echo "the number is $a"
done > test23.txt
echo "the commend is finished"



#!/bin/bash
for state in china american canda
do
    echo "$state is our visit"
done | sort
echo "the command is finished"



读取参数

#!/bin/bash
factor=1
for (( number=1; number<=$1; number++ ))
do
    factor=$[ $factor*$number ]
done
echo "the factor of $number is $factor"

sh a.sh 5 | more



读取参数

#!/bin/bash
total=$1*$2
echo "the number1=$1"
echo "the number1=$2"
echo "the total is $total"




#!/bin/bash
echo "hello $1 glad to meet you"

$ sh a.sh rich





#!/bin/bash
total=$[ ${10} * ${11} ]
echo "the number1 is ${10}"
echo "the number2 is ${11}"
echo "the total is $total"

$ sh a.sh 1 2 3 4 5 6 7 8 9 10 11
the number1 is 10
the number2 is 11



读取程序名

#!/bin/bash
echo the command entry is $0

$ sh a.sh
the command entry is a.sh


#!/bin/bash
name=`basename $0`
echo the entry is :$name




#!/bin/bash
name=`basename $0`
if [ $name = "a.sh" ]
then
    var3=$[ $1 + $2 ]
elif [ $name = "b.sh" ]
then
    var3=$[ $1*$2 ]
fi

echo $var3

$ cp a.sh b.sh

$ sh a.sh 2 5
7

$ sh b.sh 2 5
10



特殊变量

#!/bin/bash
echo there were $# apples

$ sh a.sh
there were 0 apples

$ sh a.sh 1 2 3
there were 3 apples



#!/bin/bash
if [ $# -ne 2 ]     ne : 不等于
then
    echo the usage :a b
else
    var3=$[$1 + $2 ]
fi
echo $var3


$ sh a.sh
the usage :a b

$ sh a.sh 1 2
3





#!/bin/bash
parms=$#
echo the last parmeter is $parms
echo the last parmeter is ${!#}

$ sh a.sh
the last parmeter is 0
the last parmeter is

$ sh a.sh 1 2 3
the last parmeter is 3
the last parmeter is


抓取所有的数据

#!/bin/bash
echo "using the \$* method:$*"
echo "using the \$@ method:$@"


$ sh a.sh china cnada american
using the $* method:china cnada american
using the $@ method:china cnada american






#!/bin/bash
count=1
for param in $#
do
    echo "\$# the#$count = $param"
count=$[ $count+1 ]
done
    

#!/bin/bash
count=1
for param in $@
do
    echo "\$# the#$count = $param"
count=$[ $count+1 ]
done


$ sh a.sh china american cadna
$# the#1 = 3
$# the#1 = china
$# the#2 = american
$# the#3 = cadna



移动变量

#!/bin/bash
count=1
while [ -n "$1" ]      -n str  :字符串不为空
do
    echo "the #$count = $1"
count=$[ $count +1 ]
shift
done


Administrator@MS-20170425YVKO ~
$ sh a.sh china american cadna
the #1 = china
the #2 = american
the #3 = cadna




#!/bin/bash
echo "there is orinal parmaters is $*"

shift 2
echo "the new parmaters is $1"

Administrator@MS-20170425YVKO ~
$ sh a.sh 1 2 3 4 5
there is orinal parmaters is 1 2 3 4 5
the new parmaters is 3



#!/bin/bash
echo "there is orinal parmaters is $*"

shift 2
echo "the new parmaters is $2"


$ sh a.sh 1 2 3 4 5
there is orinal parmaters is 1 2 3 4 5
the new parmaters is 4




#!/bin/bash
while [ -n "$1" ]
do
    case "$1" in
    -a) echo "found the -a is option" ;;
    -b) echo "found the -b is option" ;;
    -c) echo "found the -c is option" ;;
    *) echo "found the $1 is not option" ;;
    esac
    shift
done


$ sh a.sh -a -b -c -d
found the -a is option
found the -b is option
found the -c is option
found the -d is not option

$ sh a.sh -d -c -a
found the -d is not option
found the -c is option
found the -a is option


$ sh a.sh -a -b -c -k
found the -a is option
found the -b is option
found the -c is option
found the -k is not option




#!/bin/bash
while [ -n "$1" ]
do
    case "$1" in
    -a) echo "found the -a is option" ;;
    -b) echo "found the -b is option" ;;
    -c) echo "found the -c is option" ;;
    -d) echo "found the -d is not option" ;;
    esac
    shift
done

$ sh a.sh -a -b -c -d
found the -a is option
found the -b is option
found the -c is option
found the -d is not option


#!/bin/bash
read -p "are you done now ?" answer
case $answer in
Y | y)echo
      echo "goodbye";;
N | n)echo
      echo sorry,this is end;;
      esac
echo "this is the end of the script"

$ sh a.sh
are you done now ?y

goodbye
this is the end of the script


分离参数和选项

#!/bin/bash
while [ -n "$1" ]
do
    case "$1" in
    -a) echo "found the -a is option" ;;
    -b) echo "found the -b is option" ;;
    -c) echo "found the -c is option" ;;
    --)shift
       break ;;
    *) echo "$1 is not a option"
    esac
    shift
done

count=1
for param in $@
do
    echo "parmeter #$count: $param"
    count=$[ $count + 1 ]
done


$ sh a.sh -c -a -b test1 test2 test3
found the -c is option
found the -a is option
found the -b is option
test1 is not a option
test2 is not a option
test3 is not a option

$ sh a.sh -c -a -b -- test1 test2 test3
found the -c is option
found the -a is option
found the -b is option
parmeter #1: test1
parmeter #2: test2
parmeter #3: test3




处理带值的选项

while [ -n "$1" ]

do

    case "$1" in

    -a) echo "found the -a is option" ;;

    -b) param="$2"

        echo "found the -b option,with the parameter value $param"

        shift 2;;

    -c) echo "found the -c is option" ;;

    --) shift

        break ;;

    *) echo "$1 is not a option"

    esac

    shift

done



count=1

for parmeter in $@

do

    echo "parmeter #$count: $param"


$ sh a.sh -c -a -b test1 test2 test3
found the -c is option
found the -a is option
found the -b option,with the parameter value test1
test3 is not a option



使用optget命令

$ getopt ab:cd -a -b test1 -cd test2 test3
 -a -b test1 -c -d -- test2 test3


错误
$ getopt ab:cd -a -b test1 -cde test2 test3
getopt: unknown option -- e
 -a -b test1 -c -d -- test2 test3

忽略错误


$ getopt -q ab:cd -a -b test1 -cde test2 test3
 -a -b 'test1' -c -d -- 'test2' 'test3'


optgets 使用

#!/bin/bash
while getopts :ab:c opt
do
    case "$opt" in
    a) echo "found the -a option";;
    b) echo "found the -b option,with value $optarg";;
    c) echo "found the -c option";;
    *) echo "unknown option $opt";;
    esac
done



$ sh a.sh -ab test1 -c
found the -a option
found the -b option,with value
found the -c option

$ sh a.sh -b "test1 test2" -a
found the -b option,with value
found the -a option


$ sh a.sh -d
unknown option ?

$ sh a.sh -acde
found the -a option
found the -c option
unknown option ?
unknown option ?


#!/bin/bash
while getopts :ab:cd opt
do
    case "$opt" in
     a) echo "found the -a option";;
    b) echo "found the -b option,with value $OPTARG";;
    c) echo "fouind the -c option";;
    d) echo "found the -d option";;
    *) echo "unknown option $opt";;
    esac
done
shift $[ $OPTIND -1 ]

count=1
for param in "$@"
do
    echo "parameter $count:$param"
    count=$[ $count + 1 ]
done
 

$ sh a.sh -a -b test1 -d test1 test2 test3
found the -a option
found the -b option,with value test1
found the -d option
parameter 1:test1
parameter 2:test2
parameter 3:test3



基本的读取:

#!/bin/bash
echo -n "enter your name:"
read name
echo "hello $name ,welcome to my program"


$ sh a.sh -a -b test1 -d test1 test2 test3
enter your name:nice
hello nice ,welcome to my program



#!/bin/bash
read -p "pliase enter your age:" age
days=$[ $age * 365 ]
echo "that makes you over $days days old!"


$ sh a.sh
pliase enter your age:20
that makes you over 7300 days old!


#!/bin/bash
read -p "please enter your name:" first last
echo "checking data for $last $first"


$ sh a.sh
please enter your name:join
checking data for  join



#!/bin/bash
read -p "enter a number:"
factorial=1                           factorial因子的,阶乘的; 阶乘积,阶乘
for (( count=1; count <= $REPLY; count++ ))
do
    factorial=$[ $factorial * $count ]
done

echo "the factorial of $REPLY is $factorial"



$ sh a.sh
enter a number:5
the factorial of 5 is 120    对5进行阶乘得到的结果。这就是个阶乘公式,记住就行


超时

#!/bin/bash
if read -t 5 -p "please ener your name:"
then
    echo "hello $name.welcometo my script"
else
    echo
    echo "sorry too slow"
fi





#!/bin/bash
read -n1 -p "do you want to continue [Y/N]?" answer
case $answer in
Y | y)echo
      echo "fine.continue on...";;
N | n)echo
      echo ok,goodbye
      exit;;
esac
echo "this is the end of the script"



$ sh a.sh
do you want to continue [Y/N]?y
fine.continue on...
this is the end of the script


隐藏方式读取

#!/bin/bash
read -s -p "entr your password": pass   ------pass和:之间有空格
echo
echo "is your password really $pass?"


$ sh a.sh
entr your password:
is your password really ddd?


#!/bin/bash
read -s -p "entr your password": pass
echo "is your password really $pass?"

$ sh a.sh
entr your password:is your password really ff?


从文件中读取

#!/bin/bash
count=1
cat test | while read line
do
    echo "line $count: $line"
    count=$[ $count +1 ]
done
echo "finish prossing the file"

$ sh a.sh
line 1: nihao
line 2: nice to meet you
line 3: how are you
finish prossing the file


错误重定向

$ ls -al file 2> test



重定向错误和数据
$ ls -al test2 test3 file 2> test1 1> test4

$ cat test1
ls: 无法访问'file': No such file or directory
$ cat test4
-rw-r--r-- 1 Administrator None 4 六月  2 11:17 test2
-rw-r--r-- 1 Administrator None 0 六月  2 11:16 test3



STDERR 和 STDOUT 的输出重定向到一个文件里
$ ls -al test2 test3 file &> test5

$ cat test5
ls: 无法访问'file': No such file or directory
-rw-r--r-- 1 Administrator None 4 六月  2 11:17 test2
-rw-r--r-- 1 Administrator None 0 六月  2 11:16 test3


临时重定向

#!/bin/bash
echo "this is an error" >&2
echo "this is normal output"

$ sh a.sh
this is an error
this is normal output


$ sh a.sh 2>test5
this is normal output



永久重定向+大量数据重定量

#!/bin/bash
exec 1>testout

echo "this is a test of rediecting all output"
echo "from a script to another file"
echo "without having to redirect every individal line"


$ cat testout
this is a test of rediecting all output
from a script to another file
without having to redirect every individal line



#!/bin/bash
exec 2>testerror

echo "this is the start of the script"
echo "now reding all output to another location"

exec 1>testout

echo "this output should go to the testout file"
echo "but this should go to the testerror file" >&2


$ sh a.sh
this is the start of the script
now reding all output to another location

$ cat testerror
but this should go to the testerror file
$ cat testout
this output should go to the testout file




#!/bin/bash
exec 1>testerror

echo "this is the start of the script"
echo "now reding all output to another location"

exec 2>testout

echo "this output should go to the testout file"
echo "but this should go to the testerror file" >&2


$ cat testerror
this is the start of the script
now reding all output to another location
this output should go to the testout file


#!/bin/bash
exec 1>testerror

echo "this is the start of the script"
echo "now reding all output to another location"

exec 2>testout

echo "this output should go to the testout file"
echo "but this should go to the testerror file"


$ cat testerror
this is the start of the script
now reding all output to another location
this output should go to the testout file
but this should go to the testerror file

在脚本中重定向输入

#!/bin/bash
exec 0< testfile
count=1
while read line
do
    echo "line #count: $line"
    count=$[ $count + 1 ]
done

$ sh a.sh
line #count: this is first
line #count: this is second
line #count: this is third


将多行输入到文本里--重定向文件描述符
#!/bin/bash
exec 3>&1
exec 1>test14out
echo "this should store in the output file"
echo "along with this line"
exec 1>&3

echo "now things should be back to normal"

$ sh a.sh
now things should be back to normal

$ cat test14out
this should store in the output file
along with this line


创建输入文件描述符


#!/bin/bash
exec 6<&0

exec 0<testfile
count=1
while read line
do    
    echo "line$count:$line"
    count=$[ $count + 1 ]
done

exec 0<&6


read -n1 -p "are you done now [Y/N]?" answer
case $answer in
Y | y)echo
      echo "goodbye";;
N | n)echo
      echo sorry,this is end;;
      esac
echo "this is the end of the script"

$ sh a.sh
line1:this is first
line2:this is second
line3:this is third
are you done now [Y/N]?n
sorry,this is end
this is the end of the script



关闭文件描述附

#!/bin/bash
exec 3> test17file

echo "this is a test line of data" >&3

exec 3>&-

echo "this won't work" >&3


$ sh a.sh
a.sh:行8: 3: Bad file descriptor       ----报错




#!/bin/bash
exec 3> test17file

echo "this is a test line of data" >&3

exec 3>&-

cat test17file                    重新打开文件后就会重新执行命令。

exec 3> test17file
echo "this'll be bad" >&3

$ sh a.sh
this is a test line of data

$ cat test17file
this'll be bad

列出打开的文件描述符


$ lsof -a -p $$ -d 0.1.2   linu中可以
-bash: lsof: 未找到命令

$ /usr/sbin/lsof -a -p $$ -d 0.1.2
-bash: /usr/sbin/lsof: No such file or directory

#!/bin/bash
exec 3> test18file1
exec 6> test18file2
exec 7> testfile

/usr/sbin/losf -a -p $$ -d0.1.2.3.6.7



阻止命令输出

$ ls -al > /dev/null


创建本地临时文件


$ mktemp testing.XXXXXX  ---要大写
testing.8bFiL8


#!/bin/bash
tempfile=`mktemp test19.XXXXXX`

exec 3>$tempfile

echo "this script writes to temp file $tempfile"
echo "this is the first line" >&3

echo "this is the second line" >&3
echo "this is the third line" >&3


exec 3>&-

echo "done creating temp file. the contents are:"
cat $tempfile

rm -f $tempfile 2> /dev/null

$ sh a.sh
this script writes to temp file test19.0fqEwP
done creating temp file. the contents are:
this is the first line
this is the second line
this is the third line



在/tmp目录创建临时文件

$ mktemp -t test.XXXXXX
/tmp/test.IOH8Lo


#!/bin/bash
tempfile=`mktemp -t test.XXXXXX`
echo "this is a test file:" > $tempfile
echo "this is the second line of the fiel" >> $tempfile
echo "the temp file is located at : $tempfile"
cat $tempfile
rm -rf $tempfile

$ sh a.sh
the temp file is located at : /tmp/test.uJIoFD
this is a test file:
this is the second line of the fiel


创建临时目录

#!/bin/bash
tempdir=`mktemp -d dir.XXXXXX`
cd $tempdir
tempfile1=`mktemp temp.XXXXXX`
tempfile2=`mktemp temp.XXXXXX`

exec 7> $tempfile1
exec 8> $tempfile2

echo "seding data to the $tempdir"
echo "this is a test line of the $tempfile1" >&7
echo "this is a test line of the $tempfile2" >&8


$ sh a.sh
seding data to the dir.vvoPv0

$ ls -al
drwx------+ 1 Administrator None     0 六月  2 21:35 dir.vvoPv0

$ cd dir.vvoPv0/
$ ls
temp.aO0TU9  temp.We0nBw
$ cat temp.aO0TU9
this is a test line of the temp.aO0TU9


记录消息

tee filename    ---既显示输出,又保存到文件里

$ date | tee fielname
2017年06月 2日 周五 下午  9:45:02


$ who | tee fielname               会覆盖

Administrator@MS-20170425YVKO ~/dir.vvoPv0


$ date | tee -a fielname         追加
2017年06月 2日 周五 下午  9:49:01

$ cat fielname
2017年06月 2日 周五 下午  9:49:01




#!/bin/bash
tempfile=test22file
echo "this is the start of the test" | tee $tempfile
echo "this is the second of the test" | tee -a $tempfile
echo "this is the third of the test" | tee -a $tempfile
$ sh a.sh
this is the start of the test
this is the second of the test
this is the third of the test




控制脚本
产生信号

$ sleep 100

[1]+  已停止               sleep 100

$ ps
      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
     2052    3484    2052       6016  pty0      197108 20:37:14 /usr/bin/bash
S    7536    2052    7536       5432  pty0      197108 10:39:47 /usr/bin/sleep
     3484       1    3484       3484  ?         197108 20:37:12 /usr/bin/mintty
     4508    2052    4508       7724  pty0      197108 10:40:20 /usr/bin/ps


捕捉信号

trap command signals

#!/bin/bash
trap "echo 'sorry! I have trapped ctrl-c'" SIGINT SIGTERM
echo this is a test program
count=1
while [ $count -le 10 ]
do
    echo "loop #$count"
    sleep 5
    count=$[ $count + 1 ]
done
echo this  is the end of the test program
$ sh a.sh
this is a test program
loop #1
loop #2
loop #3
sorry! I have trapped ctrl-c
loop #4
loop #5
loop #6
loop #7
loop #8
loop #9
loop #10
this is the end of the test program


捕捉脚本的退出

#!/bin/bash
trap "echo byebye" EXIT
echo this is a test program
count=1
while [ $count -le 5 ]
do
    echo "loop #$count"
    sleep 3
    count=$[ $count + 1 ]
done
echo this  is the end of the test program
$ sh a.sh
this is a test program
loop #1
loop #2
loop #3
loop #4
loop #5
this is the end of the test program
byebye


移除捕捉   但是在脚本执行中移除 就会接受信号。

#!/bin/bash
#removing a test trap
trap "echo byebye" EXIT
count=1
while [ $count -le 5 ]
do
    echo "loop #$count"
    sleep 3
    count=$[ $count + 1 ]
done
trap - EXIT
echo "I just removed the trap"
$ sh a.sh
loop #1
loop #2
loop #3
loop #4
loop #5
I just removed the trap
$ sh a.sh
loop #1
byebye



后台运行脚本

$ sh a.sh &
[2] 2600


运行多个后台作业


在非控制台下运行脚本

$ nohup sh test &
[3] 6536

Administrator@MS-20170425YVKO ~
$ nohup: 忽略输入并把输出追加到'nohup.out'
$ cat nohup.out
loop #1
loop #2
loop #3
loop #4
loop #5
this is a test program
loop #1
I just removed the trap
loop #2
loop #3
loop #4
loop #5
this is the end of the test program
byebye
[3]-  已完成               nohup sh test




作业控制



查看作业  --后台运行且结果保存到文本里

#!/bin/bash
#testing job control
echo "this is a test program $$"
count=1
while [ $count -le 10 ]
do
    echo "loop#$count"
    sleep 5
    count=$[ $count + 1 ]
done
echo "this is end of the test program"

$ sh a.sh > test4out &
[3] 1236
$ jobs
[1]-  已停止               sleep 100  (工作目录: ~/dir.vvoPv0)
[2]+  已停止               sh a.sh
[3]   运行中               sh a.sh > test4out &
$ jobs
[1]-  已停止               sleep 100  (工作目录: ~/dir.vvoPv0)
[2]+  已停止               sh a.sh
[3]   已完成               sh a.sh > test4out
$ cat test4out
this is a test program 1236
loop#1
loop#2
loop#3
loop#4
loop#5
loop#6
loop#7
loop#8
loop#9
loop#10
this is end of the test program





作业终止后重新产生作业号

$ sh a.sh
this is a test program 4704
loop#1

[4]+  已停止               sh a.sh

$ sh a.sh
this is a test program 4336
loop#1

[3]+  已停止               sh a.sh

$ jobs -l
[1]   7536 Stopped                 sleep 100  (工作目录: ~/dir.vvoPv0)
[2]   5096 Stopped                 sh a.sh
[3]-  4336 Stopped                 sh a.sh
[4]+  4704 Stopped                 sh a.sh

$ kill -9 4704



重启停止的作业

后台重启进程
bg + 2 (作业号)

前台重启进程

fg + 作业号



优先级  -10 --10   -10的优先级最大
nice 命令



调低优先级
$ nice -n 10 sh a.sh > test4out &
[4] 8032




$ ps al
      PID    PPID    PGID     WINPID   TTY         UID    STIME COMMAND
S    4336    2052    4336       3456  pty0      197108 11:37:45 /usr/bin/sh
     8032    2052    8032       5644  pty0      197108 20:10:33 /usr/bin/sh
     2052    3484    2052       6016  pty0      197108 20:37:14 /usr/bin/bash
S    7536    2052    7536       5432  pty0      197108 10:39:47 /usr/bin/sleep
     3484       1    3484       3484  ?         197108 20:37:12 /usr/bin/mintty
     6168    2052    6168       4760  pty0      197108 20:10:55 /usr/bin/ps
S    4316    4336    4336       4216  pty0      197108 20:06:15 /usr/bin/sleep
     4868    8032    8032       5112  pty0      197108 20:10:50 /usr/bin/sleep


调高优先级 只能是管理员调高
$ nice -n -10 sh a.sh &
[5] 4396
[4]   已完成               nice -n 10 sh a.sh > test4out



renice  调高正在运行的程序
$ renice -10 -p 1452
1452 (进程 ID) 旧优先级为 0,新优先级为 -10




定时运行作业


at [ -f fielname ] time

at -f test5 8:38



列出等待的作业

$$atq



删除作业  atrm 59





计划定期执行脚本

min hour dayfmonth month dayofweek command

每天的10:15运行一个命令

15 10 * * * command

每周一4:15运行命令

15 16 * * 1 command


每个月的第一天中午12点 执行命令

00 12 1 * * command

15 10 * * * /home/rich/test4 > test4out


anacronc程序  :当电脑重启的时候 自动执行




定义自己的开机脚本   各个版本不同 放的位置不一样

ubuntu 在 /etc/rc.local  修改


定了系统后 不同的用户 在 .bashrc 下改动脚本






定义函数

function name {
    commands

}



#!/bin/bash
function func1 {
    echo "this is an exanple of a function"
}

count=1
while [ $count -le 5 ]
do
    func1
    count=$[ $count +1 ]
done

echo "this is the end of the loop"
func1
echo "now this is the end of the script"
$ sh a.sh
this is an exanple of a function
this is an exanple of a function
this is an exanple of a function
this is an exanple of a function
this is an exanple of a function
this is the end of the loop
this is an exanple of a function
now this is the end of the script
    






重新定义函数后  第二个会覆盖原来的函数输出

#!/bin/bash
#testing using a duplicate function name

function func1 {
echo "thie is the first definition of the function name"
}


func1

function func1 {
    echo "this is a repeat of the name function name"


}

func1
echo "this is the end of the scripts"
$ sh a.sh
thie is the first definition of the function name
this is a repeat of the name function name
this is the end of the scripts




默认退出状态码:以最后一条命令是否执行成功为准



#!/bin/bash
#testing using a duplicate function name

func1() {
    echo "trying to display a non-existent file"
    ls -l dadfile
}
echo "testing the function:"
func1

echo "the exist status is :$?"
$ sh a.sh
testing the function:
trying to display a non-existent file
ls: 无法访问'dadfile': No such file or directory
the exist status is :2



倒换最后一个函数位置

#!/bin/bash
#testing using a duplicate function name

func1() {
    ls -l dadfile
    echo "trying to display a non-existent file"
}
echo "testing the function:"
func1

echo "the exist status is :$?"
$ sh a.sh
testing the function:
ls: 无法访问'dadfile': No such file or directory
trying to display a non-existent file
the exist status is :0



使用return命令  (0-255之间)


#!/bin/bash
#using the return command in a return

function db1 {
    read -p "enter a value :" value
    echo "doubling the value"
    return $[ $value * 2 ]
}

db1

echo "the new value is $?"
$ sh a.sh
enter a value :100
doubling the value
the new value is 200
$ sh a.sh
enter a value :200
doubling the value
the new value is 144




使用函数输出

#!/bin/bash
#using the ehco to return a value

function db1 {
    read -p "enter a value :" value
    echo $[ value * 2 ]
}

result=`db1`
echo "the new value is $result"
$ sh a.sh
enter a value :5
the new value is 10





向函数中传递参数


#!/bin/bash
#passing paraneters to a function

function addem {
    if [ $# -eq 0 ] || [ $# -gt 2 ]    
    then
        echo -1
    elif [ $# -eq 1 ]
    then 
        echo $[ $1 + $1 ]
    else
        echo $[ $1 + $2 ]
    fi

}

echo -n "adding 10 and 15:"

value=`addem 10 15`
echo $value
echo -n "let's trying juest one number:"
value=`addem 10`
echo $value
echo -n "now trying adding on numbers:"
value=`addem`
echo $value
echo -n "finally,try adding three numbers:"
value=`addem 10 15 20`
echo $value
$ sh a.sh
adding 10 and 15:25
let's trying juest one number:20
now trying adding on numbers:-1
finally,try adding three numbers:-1




报错

#!/bin/bash
#passing paraneters to a function

function badfunc1 {
    echo $[ $1 * $2 ]

}
if [ $# -eq 2 ]
then
    value=`badfunc1`
    echo "the result is $value"
else
    echo "usage:badtest1 a b"
fi
$ sh a.sh 2 3
a.sh:行5: *  : 语法错误: 需要操作数 (错误符号是 "*  ")
the result is
    


正确

#!/bin/bash
#passing paraneters to a function

function func7 {
    echo $[ $1 * $2 ]

}
if [ $# -eq 2 ]
then
    value=`func7 $1 $2`
    echo "the result is $value"
else
    echo "usage:badtest1 a b"
fi
$ sh a.sh 2 3
the result is 6




在函数中处理变量


#!/bin/bash
#using a global variable to pass a value

function db1 {
    value=$[ $value *2 ]
}

read -p "enter a value:" value
db1
echo "the new value is $value"
$ sh a.sh
enter a value:45
the new value is 90



产生错误

#!/bin/bash
#using a global variable to pass a value

function func1 {
    temp=$[ $value + 5 ]
    result=$[ $temp *2 ]
 
}

temp=4
value=6

func1
echo "the result is $result"
if [ $temp -gt $value ]
then
    echo "temp is larger"
else
    echo "temp is smaller"
fi
$ sh a.sh
the result is 22
temp is larger




局部变量

local temp
local temp=$[ $value +5 ]

#!/bin/bash
#using a global variable to pass a value

function func1 {
    local temp=$[ $value + 5 ]
    result=$[ $temp *2 ]
 
}

temp=4
value=6

func1
echo "the result is $result"
if [ $temp -gt $value ]
then
    echo "temp is larger"
else
    echo "temp is smaller"
fi
$ sh a.sh
the result is 22
temp is smaller




数组函数和变量

1、向函数传递组参数


#!/bin/bash
#trying to pass an array varianble

function testit {
    echo "the parameters are:$@"
    thisarray=$1
    echo "the received arrary is ${thisarray[*]}"    
}

myarray=(1 2 3 4 5)
echo "the  original arrary is: ${myarray[*]}"
testit $myarrary
$ sh a.sh
the  original arrary is: 1 2 3 4 5
the parameters are:
the received arrary is



#!/bin/bash
#array variable to function test

function testit {
    local newarray
    newarray=(`echo "$@"`)
    echo "the new array value is: ${newarray[*]}"

}

myarray=(1 2 3 4 5)
echo "the orinagal array is ${myarray[*]}"
testit ${myarray[*]}
$ sh a.sh
the orinagal array is 1 2 3 4 5
the new array value is: 1 2 3 4 5



function testit {
    local newarray
    newarray=(`echo "$@"`)
    echo "the new array value is: ${newarray[*]}"

}

myarray=(1 2 3 4 5)
testit ${myarray[*]}
$ sh a.sh
the new array value is: 1 2 3 4 5




#!/bin/bash
#adding values in an array

function addarray {
    local sum=0
    local newarray
    newarray=(`echo "$@"`)
    for value in ${newarray[*]}
    do
        sum=$[ $sum + $value ] 
    done
    echo $sum

}

myarray=(1 2 3 4 5)
echo "the original array is:${myarray[*]}"
argl=`echo ${myarray[*]}`
result=`addarray $argl`
echo "the result is $result"
$ sh a.sh
the original array is:1 2 3 4 5
the result is 15



    
#!/bin/bash
#adding values in an array

function addarray {
    local sum=0
    local newarray
    newarray=(`echo "$@"`)
    for value in ${newarray[*]}
    do
        sum=$[ $sum + $value ] 
    done
    echo $sum

}

myarray=(1 2 3 4 5)
addarray ${myarray[*]
$ sh a.sh
15







从函数返回数组


#!/bin/bash
#return an array value

function arraydblr {
    local origarray
    local newarray
    local elements
    local i
    origarray=(`echo "$@"`)
    newarray=(`echo "$@"`)
    elements=$[ $# - 1 ]
    for (( i = 0; i <= $elements; i++ ))
    do
        
    newarray[$i]=$[ ${origarray[$i]} * 2 ] 
    
    done
    echo ${newarray[*]}

}

myarray=(1 2 3 4 5)
echo "the original array is: ${myarray[*]}"
argl=`echo ${myarray[*]}`
result=(`arraydblr $argl`)
echo "the new array is:${result[*]}"
$ sh a.sh
the original array is: 1 2 3 4 5
the new array is:2 4 6 8 10





函数递归

#!/bin/bash
#using recursion
function factorial {
    if [ $1 -eq 1 ]
    then
        echo 1
    else
        local temp=$[ $1 -1 ]
        local result=`factorial $temp`
        echo $[ $result * $1 ]
fi


}


read -p "enter value:" value
result=`factorial $value`
echo "the factiral of $value is : $result"
$ sh a.sh
enter value:5
the factiral of 5 is : 120




创建库


在命令行创建函数

$ function divm { echo $[ $1 / $2 ];}

Administrator@MS-20170425YVKO ~
$ divm 100 5
20



$ function doubleit { read -p "enter calue:" value; echo $[ $value * 2 ]; }
$ doubleit
enter calue:20
40



$ function multem {
> echo $[ $1 * $2 ]
> }
$ multem 2 5
10





在.bashrc文件中定义函数





图形化脚本工具



初识sed和gwk


在命令行定义编辑器

$ echo "this is a test" | sed 's/test/big test/'
this is a big test


$ cat data1
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
$ sed 's/dog/cat/' data1
the quick brown fox jumps over the lazy cat.
the quick brown fox jumps over the lazy cat.
the quick brown fox jumps over the lazy cat.
the quick brown fox jumps over the lazy cat.
the quick brown fox jumps over the lazy cat.
$ cat data1
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.




在命令行使用多个编辑器

$ sed -e 's/brown/green/; s/dog/cat/' data1
the quick green fox jumps over the lazy cat.
the quick green fox jumps over the lazy cat.
the quick green fox jumps over the lazy cat.
the quick green fox jumps over the lazy cat.
the quick green fox jumps over the lazy cat.


$ sed -e '
s/brown/green/
s/fox/element/
s/dog/cat/' data1
the quick green element jumps over the lazy cat.
the quick green element jumps over the lazy cat.
the quick green element jumps over the lazy cat.
the quick green element jumps over the lazy cat.
the quick green element jumps over the lazy cat.





从文件中读取编辑器命令

$ vi script1
s/brown/green/
s/fox/elephant/
s/dog/cat/
$ cat data1
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
the quick brown fox jumps over the lazy dog.
$ sed -f script1 data1
the quick green elephant jumps over the lazy cat.
the quick green elephant jumps over the lazy cat.
the quick green elephant jumps over the lazy cat.
the quick green elephant jumps over the lazy cat.
the quick green elephant jumps over the lazy cat.





gawk程序

$ gawk '{print "hello john!"}'
this is a test
hello john!
hello
hello john!
this is another test
hello john!




$ cat data1
one line of test text
two lines of tesr text
three lines of test text
$ gawk '{print $1}' data1
one
two
three



在程序脚本中使用多个命令

$ echo "my name is rich" | gawk '{$4="christime";print $0}'
my name is christime


$ gawk '{
> $4="testing"
> print $0}'
this is not a good test
this is not testing good test




从文件中读取数据

$ cat script1
{ print $1 "'s home directory is" $6 }
$ gawk -F: -f script1 /etc/passwd


$ cat script1
{
text = "'s home dictionary is"
print $1 text $6
}
$ gawk -F: -f script1 /etc/passwd




在处理数据前运行脚本

$ gawk 'BEGIN {print "hello world"}'
hello world





$ gawk 'BEGIN {print "the data1 file contenes:"} {print $0}' data1
the data1 file contenes:
one line of test text
two lines of tesr text
three lines of test text



在处理脚本后运行脚本

$ gawk 'BEGIN {print "the data1 file contenes:"} {print $0} END {print "end of the file"}' data1
the data1 file contenes:
one line of test text
two lines of tesr text
three lines of test text
end of the file




BEGIN {
print "the latest list of users and shells"
print "userid shell"
print "---------"
FS=":"
}

{
print $1  "   "$7"
}

END {

print "this concludes the listing"
}
$ gawk -f script1 /etc/passwd





sed编辑器基础


更多的替换选项

替换标记

$ cat data1
this is a test of the test script
this is the second test of the test sceript
$ sed 's/test/trial/' data1
this is a trial of the test script
this is the second trial of the test sceript
$ sed 's/test/trial/2' data1
this is a test of the trial script
this is the second test of the trial sceript
$ sed 's/test/trial/g' data1
this is a trial of the trial script
this is the second trial of the trial sceript



$ cat test2
this is a test line
this is a different line
$ sed -n 's/test/trial/p' test2   -n:阻止整个输出,p:只输出被修改的行
this is a trial line





$ sed 's/test/trial/w test' test2
this is a trial line
this is a different line
$ cat test
this is a trial line




替换字符

$ sed 's!/bin/bash!/bin/csh' /etc/passwd



使用地址  作用于特定行




数字方式的行寻址



$ cat data1
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
$ sed '2s/dog/cat/' data1                         只作用第二行
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy cat
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
$ sed '2,3s/dog/cat/' data1                       作用2,3行范围         
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy cat
the quick brown fox jumps over the lazy cat
the quick brown fox jumps over the lazy dog
$ sed '2,$s/dog/cat/' data1              作用第二行到末行                 
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy cat
the quick brown fox jumps over the lazy cat
the quick brown fox jumps over the lazy cat



另一种方式

$ sed '/dog/s/lazy/dog/' data1
the quick brown fox jumps over the dog dog
the quick brown fox jumps over the dog dog
the quick brown fox jumps over the dog dog
the quick brown fox jumps over the dog dog




组合命令


$ cat data1
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
$ sed '2{
s/fox/elements/
s/dog/cat/
}' data1
the quick brown fox jumps over the lazy dog
the quick brown elements jumps over the lazy cat
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog


$ sed '3,${                                     作用 到末行
s/fox/elements/
s/dog/cat/
}' data1
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
the quick brown elements jumps over the lazy cat
the quick brown elements jumps over the lazy cat




删除行


$ cat data1
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
$ sed 'd' data1                                  不管用
$ cat data1
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
$ sed '3d' data1
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog
the quick brown fox jumps over the lazy dog



$ cat data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4
$ sed '3d' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 4
$ sed '2,3d' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 4
$ sed '3,$d' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
$ sed '/dog 1/d' data1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4
$ sed '/dog 2/d' data1                          匹配删除--不怎么管用。
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4
$ sed '/1/,/3/d' data1
the quick brown fox jumps over the lazy dog 4





插入和附加文本


$ echo "test line 2" | sed 'i\test line 1'
test line 1
test line 2
$ echo "test line 2" | sed 'a\test line 1'
test line 2
test line 1


命令行界面输入

$ echo "test line 2" | sed 'i\
> test line 1'
test line 1
test line 2



$ cat data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4
$ sed '3i\
> this is  a insert line.' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
this is  a insert line.
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4
$ sed '3a\
> this is a append line.' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
this is a append line.
the quick brown fox jumps over the lazy dog 4
$ sed '$a\
> this is a new line' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4
this is a new line
$ sed '1i\
this is a new line' data1
this is a new line
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4




修改行


$ cat data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4
$ sed '3c\
> this is a change line' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
this is a change line
the quick brown fox jumps over the lazy dog 4
$ sed '/dog 3/c\                                  文本模式寻址;
this is a change line.' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
this is a change line.
the quick brown fox jumps over the lazy dog 4
$ sed '/dog 1/c\
this is change line.' data1
this is change line.
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4
$ sed '2,3c\                                     不是想要的结果
this is change line.' data1
the quick brown fox jumps over the lazy dog 1
this is change line.
the quick brown fox jumps over the lazy dog 4




转换命令  --唯一处理单个字符



$ cat data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4
$ sed 'y/1234/5678/' data1
the quick brown fox jumps over the lazy dog 5
the quick brown fox jumps over the lazy dog 6
the quick brown fox jumps over the lazy dog 7
the quick brown fox jumps over the lazy dog 8

$ echo "this 1 is a test of 1 try" | sed 'y/123/456/'
this 4 is a test of 4 try




回顾打印


$ echo "this is a test" | sed 'p'
this is a test
this is a test
$ sed -n '/dog 3/p' data1
the quick brown fox jumps over the lazy dog 3
$ sed -n '2,3p' data1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
$ sed -n '/3/{
> p
> s/dog/cat/p
> }' data1
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy cat 3



打印行号


$ sed '=' data1
1
the quick brown fox jumps over the lazy dog 1
2
the quick brown fox jumps over the lazy dog 2
3
the quick brown fox jumps over the lazy dog 3
4
the quick brown fox jumps over the lazy dog 4
$ sed -n '/dog 3/{
=
p
}' data1
3
the quick brown fox jumps over the lazy dog 3





列出行


$ sed -n 'l' data9
this line contains an escape character$





用sed和文件一起工作


1、向文件写入



$ sed '1,2w test' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy dog 3
the quick brown fox jumps over the lazy dog 4
$ cat test
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2





the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy cat 3
the quick brown fox jumps over the lazy cat 4
$ sed -n '/dog/w test' data1
$ cat test
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2





 


从文件中读取数据



$ cat test
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
$ sed '4r test' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy cat 3
the quick brown fox jumps over the lazy cat 4
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2



$ cat test
this is a hot
this is a bug
$ sed '/dog 2/r test' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
this is a hot
this is a bug

the quick brown fox jumps over the lazy cat 3
the quick brown fox jumps over the lazy cat 4
$ sed '$r test' data1                           添加到末尾   
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy cat 3
the quick brown fox jumps over the lazy cat 4

this is a hot
this is a bug
$ sed '4r test' data1
the quick brown fox jumps over the lazy dog 1
the quick brown fox jumps over the lazy dog 2
the quick brown fox jumps over the lazy cat 3
the quick brown fox jumps over the lazy cat 4
this is a hot
this is a bug



占位文本


$ cat test
blum.ate        chicago.il
mullen.riley    west lafayette.in
$ sed '/LIST/{
r test
d
}' latter
would the following people:
blum.ate        chicago.il
mullen.riley    west lafayette.in
please report to the office.





正则表达式


$ echo "this is line number 1" | sed -n '/ber 1/p'
this is line number                     -- 什么也没有
$ echo "this is line number1" | sed -n '/ber 1/p'




特殊字符


$ sed -n '/\$/p' data2   特殊字符作为文本字符必须转义
the cost is $4.00
$ echo "\ is a special character" | sed -n '/\\/p'        反斜线
\ is a special character                    
$ echo "3 /2 " | sed -n '///p'
sed:-e 表达式 #1,字符 3:未知的命令:“/        斜线需要转义
$ echo "3 / 2" | sed -n '/\//p'
3 / 2




锚字符



脱字符  ---必须要匹配行首

$ echo "the books store" | sed -n '/^book/p'
$ echo "books are gteat" | sed -n '/^book/p'
books are gteat
$ sed -n '/^this/p' data3
this is a  test line
this is another test line
$ echo "this ^ is a test" | sed -n '/s ^/p'    不放在开头^ 就是普通字符
this ^ is a test



锁定在行尾



$ echo "this is  a good book" | sed -n '/book$/p'
this is  a good book
$ echo "this is  a good book" | sed -n ' /$good/p'   报错:空

$ echo "this is  a good books" | sed -n ' /book$/p'   空
$ echo "this is  a good books" | sed -n '/s$/p'
this is  a good books



组合锚点


$ cat data4
this is a test  of both anchors
i said this is a test
this is a test
I'm sure this is a test
$ sed -n '/^this is a test$/p' data4
this is a test
$ cat data4
this is one test line


this is another test line
$ sed '/^$/d' data4                   过滤掉空格行
this is one test line
this is another test line





点字符


$ cat data4
this is a test of a line
the cat is sleeping
that is a very nice hat
this test is at line four
at the o'clock we'ii go home
$ sed -n '/.at/p' data4
the cat is sleeping
that is a very nice hat
this test is at line four           空格会被当作字符匹配





字符组



$ cat data4
this is a test of a line
the cat is sleeping
that is a very nice hat
this test is at line four
$ sed -n '/[ch]at/p' data4
the cat is sleeping
that is a very nice hat
$ echo "Yes" | sed -n '/[Yy]es/p'   不太确定时候很有用。
Yes




单个表达式中用多个字符组


$ echo "Yes" | sed -n '/[Yy][Ee][Ss]/p'
Yes
$ echo "yEs" | sed -n '/[Yy][Ee][Ss]/p'
yEs




字符组也可以使用数字



$ cat data4
this line doesn't contain a number
this line has 1 number in it
this line a number 2 on it
this line has a number 4 in it
$ sed -n '/[0123]/p' data4
this line has 1 number in it
this line a number 2 on it




匹配邮编

$ cat data1
60633
46201
223001
4353
22203
$ sed -n '/[0123456789][0123456789][0123456789][0123456789][0123456789]/p' data1
60633
46201
223001
22203
$ sed -n '/^[0123456789][0123456789][0123456789][0123456789][0123456789]$/p' data1
60633
46201
22203


排错单词

$ cat data1
I need to have some maintenence dong on my car
I'll pay that in a seperate invoice
after i pay for the maintenance my car will be as good as new
$ sed -n '
/maint[ea]n[ae]nce/p
/sep[ea]r[ea]te/p' data1
I need to have some maintenence dong on my car
I'll pay that in a seperate invoice
after i pay for the maintenence my car will be as good as new




排错字符组


$ sed -n '/[ch]at/p' data1
i have a cat
i have a hat
$ sed -n '/[^ch]at/p' data1
i have a nat






使用区间

$ cat data1
60633
46201
223001
4353
22203
$ sed -n '/^[0-9][0-9][0-9][0-9][0-9]$/p' data1
60633
46201
22203



$ cat data1
i have a cat
i have a hat
i have a nat
$ sed -n '/[c-h]at/p' data1
i have a cat
i have a hat
$ sed -n '/[a-c n-t]at/p' data1   多个区间
i have a cat
i have a nat



特殊字符组


$ echo "abc" | sed -n '/[[:digit:]]/p'


$ echo "abc" | sed -n '/[[:alpha:]]/p' 
abc
$ echo "abc123" | sed -n '/[[:digit:]]/p'   匹配数字
abc123
$ echo "this is. a test" | sed -n '/[[:punct:]]/p'   匹配标点符号
this is. a test
$ echo "this is a test" | sed -n '/[[:punct:]]/p'   空

Administrator@MS-20170425YVKO ~






星号  -表明在文本中出现一次或多次


$ echo "ik" | sed -n '/ie*k/p'
ik
$ echo "iek" | sed -n '/ie*k/p'
iek
$ echo "ieek" | sed -n '/ie*k/p'
ieek
$ echo "ieeek" | sed -n '/ie*k/p'
ieeek
$ echo "ieeeek" | sed -n '/ie*k/p'
ieeeek





用在句子中 防止单词拼写错

$ echo "I'm getting a color tv " | sed -n '/colou*r/p'
I'm getting a color tv
$ echo "I'm getting a colour tv " | sed -n '/colou*r/p'
I'm getting a colour tv




.*全部匹配


$ echo "this is a regular pattern expression" | sed -n '
/regular.*expression/p'
this is a regular pattern expression


$ echo "bt" | sed -n '/b[ae]*t/p'
bt
$ echo "bat" | sed -n '/b[ae]*t/p'
bat
$ echo "batt" | sed -n '/b[ae]*t/p'
batt
$ echo "bett" | sed -n '/b[ae]*t/p'
bett
$ echo "baatt" | sed -n '/b[ae]*t/p'
baatt
$ echo "baaeeett" | sed -n '/b[ae]*t/p'
baaeeett
$ echo "baaeaaeet" | sed -n '/b[ae]*t/p'
baaeaaeet
$ echo "baaekeett" | sed -n '/b[ae]*t/p'   失败

Administrator@MS-20170425YVKO ~





扩展正则表达式



问号  ---只匹配0次或1次


$ echo "bt" | gawk '/be?t/{print $0}'
bt
$ echo "bet" | gawk '/be?t/{print $0}'
bet
$ echo "beet" | gawk '/be?t/{print $0}'    失败

Administrator@MS-20170425YVKO ~
$ echo "beeet" | gawk '/be?t/{print $0}'      失败

Administrator@MS-20170425YVKO ~



$ echo "bt" | gawk '/b[ae]?t/{print $0}'
bt
$ echo "bat" | gawk '/b[ae]?t/{print $0}'
bat
$ echo "bot" | gawk '/b[ae]?t/{print $0}'   报错

Administrator@MS-20170425YVKO ~
$ echo "bet" | gawk '/b[ae]?t/{print $0}'
bet
$ echo "baet" | gawk '/b[ae]?t/{print $0}'    0或1次  a和e只能选一个。
Administrator@MS-20170425YVKO ~
$ echo "beat" | gawk '/b[ae]?t/{print $0}'    0或1次  a和e只能选一个

Administrator@MS-20170425YVKO ~
$ echo "beet" | gawk '/b[ae]?t/{print $0}'

Administrator@MS-20170425YVKO ~





加号   :出现一次或多次  但必须出现一次


$ echo "beeet" | gawk '/be+t/{print $0}'
beeet
$ echo "beet" | gawk '/be+t/{print $0}'
beet
$ echo "bet" | gawk '/be+t/{print $0}'
bet
$ echo "bt" | gawk '/be+t/{print $0}'        报错

Administrator@MS-20170425YVKO ~



$ echo "bt" | gawk '/b[ae]+t/{print $0}'    报错

Administrator@MS-20170425YVKO ~
$ echo "bat" | gawk '/b[ae]+t/{print $0}'
bat
$ echo "baet" | gawk '/b[ae]+t/{print $0}'
baet
$ echo "beet" | gawk '/b[ae]+t/{print $0}'
beet
$ echo "beeat" | gawk '/b[ae]+t/{print $0}'
beeat





使用花括号




$ echo "bt" | gawk --re-interval '/be{1}t/{print $0}'


Administrator@MS-20170425YVKO ~
$ echo "bet" | gawk --re-interval '/be{1}t/{print $0}'
bet
$ echo "beet" | gawk --re-interval '/be{1}t/{print $0}'     报错

Administrator@MS-20170425YVKO ~



$ echo "bt" | gawk --re-interval '/be{1,2}t/{print $0}'

Administrator@MS-20170425YVKO ~
$ echo "bet" | gawk --re-interval '/be{1,2}t/{print $0}'
bet
$ echo "beet" | gawk --re-interval '/be{1,2}t/{print $0}'
beet
$ echo "beeet" | gawk --re-interval '/be{1,2}t/{print $0}'    报错

Administrator@MS-20170425YVKO ~




只能a和b一共任意两个才可以

$ echo "bt" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'

Administrator@MS-20170425YVKO ~
$ echo "bat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
bat
$ echo "beat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
beat
$ echo "beet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'
beet
$ echo "beeat" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'  报错

Administrator@MS-20170425YVKO ~
$ echo "baeet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'    报错

Administrator@MS-20170425YVKO ~
$ echo "baeaet" | gawk --re-interval '/b[ae]{1,2}t/{print $0}'

Administrator@MS-20170425YVKO ~                    报错






管道符号


$ echo "the cat is asleep" | gawk '/cat|dog/{print $0}'
the cat is asleep
$ echo "the dog is asleep" | gawk '/cat|dog/{print $0}'
the dog is asleep
$ echo "the sheep is asleep" | gawk '/cat|dog/{print $0}'

Administrator@MS-20170425YVKO ~
$ echo "she has a hat" | gawk '/[ch]at|dog/{print $0}'
she has a hat




聚合表达式


$ echo "Sat" | gawk '/Sat(urday)?/{print $0}'
Sat
$ echo "Saturday" | gawk '/Sat(urday)?/{print $0}'
Saturday
$ echo "Saturday" | gawk '/Sat(urday)/{print $0}'   自己写的
Saturday




$ echo "cat" | gawk '/(c|b)a(b|t)/{print $0}'
cat
$ echo "cab" | gawk '/(c|b)a(b|t)/{print $0}'
cab
$ echo "bat" | gawk '/(c|b)a(b|t)/{print $0}'
bat
$ echo "tab" | gawk '/(c|b)a(b|t)/{print $0}'

Administrator@MS-20170425YVKO ~
$ echo "tac" | gawk '/(c|b)a(b|t)/{print $0}'

Administrator@MS-20170425YVKO ~







实用中的正则表达式







目录文件计数


$ echo $PATH | sed 's/:/ /g'
/usr/local/bin /usr/bin /cygdrive/c/Windows/system32 /cygdrive/c/Windows /cygdrive/c/Windows/System32/Wbem /cygdrive/c/Windows/System32/WindowsPowerShell

mypath=`echo $PATH | sed 's/:/ /g'`
for directory in $mypath
do
print $directory
done
$ sh test
??Ч????? - /usr
??Ч????? - /usr
??Ч????? - /cygdrive
??Ч????? - /cygdrive
??Ч????? - /cygdrive
??Ч????? - /cygdrive


#!/bin/bash
#count number of files in your PATH
mypath=`echo $PATH | sed 's/:/ /g'`
count=0
for directory in $mypath
do
    check=`ls $directory`
    for item in $check
    do
        count=$[ $count + 1 ]
    done
    echo "$directory - $count"
    count=0
done
$ sh test
/usr/local/bin - 0
/usr/bin - 352
/cygdrive/c/Windows/system32 - 2998
/cygdrive/c/Windows - 109
/cygdrive/c/Windows/System32/Wbem - 280
/cygdrive/c/Windows/System32/WindowsPowerShell/v1.0 - 22





匹配电话号码



#!/bin/bash
#script to filter out bad phone numbers
gawk --re-interval '/^\(?[2-9][0-9]{2}\)?(| |-|\.)[0-9]{3}( |-|\.)[0-9]{4}/{print $0}'
$ echo "317-555-1234" | sh isphone
317-555-1234


$ cat phonelist
000-000-000
123-456-7890
212-555-1234
(317)555-1234
(202) 555-9876
33523
1234567890
234.123.4567
$ cat phonelist | sh isphone
212-555-1234
(317)555-1234
(202) 555-9876
234.123.4567




解析邮件地址


gawk --re-interval '/^([a-zA-Z0-9_\-\.\+]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})/{print $0}'
$ echo "rich@here.now" | sh ise-mail
rich@here.now
$ echo "rich@here.n" | sh ise-mail

Administrator@MS-20170425YVKO ~
$ echo "rich@here-now" | sh ise-mail

Administrator@MS-20170425YVKO ~
$ echo "rich.blum@here.now" | sh ise-mail
rich.blum@here.now
$ echo "rich_blum@here.now" | sh ise-mail
rich_blum@here.now
$ echo "rich/blum@here.now" | sh ise-mail

Administrator@MS-20170425YVKO ~
$ echo "rich#blum@here.now" | sh ise-mail

Administrator@MS-20170425YVKO ~
$ echo "rich*blum@here.now" | sh ise-mail

Administrator@MS-20170425YVKO ~




sed进阶

多行命令

next命令



$ cat data1       -------------目的要删除首行后面的空格
t$ cat data1
this is the header line

this is the data line

this is the last line


$ sed '/^$/'d data1
this is the header line
this is the header line
this is the header line
$ sed '/header/{n ; d}' data1
this is the header line
this is the data line

this is the last line





合并文本行


this is the header line
this is the first data line
this is the second data line
this is the last line
$ sed '/first/{N ; s/\n/ /}' data1
this is the header line
this is the first data line this is the second data line
this is the last line


替换短语

the first meeting of the Linux System
Administrator's group will be held on Tuesday
All System Administrators should attend this meeting
Thank you for your attendance
$ sed 's/System Administrators/Desktop User/' data1
the first meeting of the Linux System
Administrator's group will be held on Tuesday
All Desktop User should attend this meeting
Thank you for your attendance




错行连起来替换短语


the first meeting of the Linux System
Administrator's group will be held on Tuesday
All System Administrators should attend this meeting
Thank you for your attendance


有缺陷

$ sed 'N ; s/System.Administrator/Desktop User/' data1
the first meeting of the Linux Desktop User's group will be held on Tuesday
All Desktop Users should attend this meeting
Thank you for your attendance



解决办法


$ sed '
N
s/System\nAdministrator/Desktop\nUser/
s/System Administrator/Desktop User/
' data1
the first meeting of the Linux Desktop
User's group will be held on Tuesday
All Desktop Users should attend this meeting
Thank you for your attendance


有缺陷



$ sed '
> N
> s/System\nAdministrator/Desktop\nUser/
> s/System Administrators/Desktop/
> ' data1
the first meeting of the Linux Desktop
User's group will be held on Tuesday
All Desktop should attend this meeting




解决办法


$ sed '
> s/System Administrators/Desktop/
> N
> s/System\nAdministrator/Desktop\nUser/
> ' data1
the first meeting of the Linux Desktop
User's group will be held on Tuesday
All Desktop should attend this meeting





多行删除命令


会删除所有,不是想要的

$ sed 'N ; /System\nAdministrator/d' data1
All System Administrators should attend this meeting






D 只会删除含换行符的所有字符




$ sed 'N ; /System\nAdministrator/D' data1
Administrator's group will be held on Tuesday
All System Administrators should attend this meeting




删除数据流中出现在第一行前的空白行



$ cat data1

this is the header line
this is a data line

this is the last line
$ sed '/^$/{N ; /header/D}' data1
this is the header line
this is a data line

this is the last line






只打印第一行


$ cat data1
the first meeting of the Linux System
Administrator's group will be held on Tuesday
All System Administrators should attend this meeting
Thank you for your attendance
$ sed -n 'N ; /System\nAdministrator/P' data1
the first meeting of the Linux System






模式空间:可以让第一个数据行出现在第二个数据行之后



$ cat data1
this is the header line
this is the first data line
this is the first data line
this is the last line

$ sed -n '/first/{
> h
> p
> n
> p
> g
> p
> }' data1
this is the first data line
this is the second data line
this is the first data line



$ sed -n '/first/{
> h
> n
> p
> g
> p
> }' data1
this is the second data line
this is the first data line





排除命令   ---让命令失去作用



$ cat data1
this is the header line
this is the first data line
this is the second data line
this is the last line

$ sed -n '/header/!p' data1
this is the first data line
this is the second data line
this is the last line




不打印最后一行

$ cat data1
the first meeting of the Linux System
Administrator's group will be held on Tuesday
All System Administrators should attend this meeting
Thank you for your attendance
$ sed 'N ; s/System.Administrator/Desktop User/' data1
the first meeting of the Linux Desktop User's group will be held on Tuesday
All Desktop Users should attend this meeting
Thank you for your attendance



打印最后一行

$ cat data1
the first meeting of the Linux System
Administrator's group will be held on Tuesday
All System Administrators should attend this meeting

$ sed '$!N; s/System.Administrator/Desktop User/' data1
the first meeting of the Linux Desktop User's group will be held on Tuesday
All Desktop Users should attend this meeting





反转文本打印



$ cat data1
this is the header line
this is the first data line
this is the second data line
this is the last line

$ sed -n '{1!G ; h ; $p}' data1

this is the last line
this is the second data line
this is the first data line
this is the header line
$ sed -n '{G ; h ; $p}' data1   自己写的

this is the last line
this is the second data line
this is the first data line
this is the header line






改变流


跳转



$ cat data1
this is the header line
this is the first data line
this is the second data line
this is the last line

$ sed '{2,3b ; s/this is /IS this/;s/line/test?/}' data1
IS thisthe header test?
this is the first data line
this is the second data line
IS thisthe last test?




$ cat data1
this is the header line
this is the first data line
this is the second data line
this is the last line
$ sed '{/first/b jump1 ; s/this is the/No jump on/
:jump1
s/this is the/jump here on/}' data1
No jump on header line
jump here on first data line
No jump on second data line
No jump on last line




跳转循环



$ echo "this, is, a, test, to, remove, commas," | sed -n '{
:start
s/,//1p
b start
}'
this is, a, test, to, remove, commas,
this is a, test, to, remove, commas,
this is a test, to, remove, commas,
this is a test to, remove, commas,
this is a test to remove, commas,
this is a test to remove commas,
this is a test to remove commas



无限循环   要想防止无限循环 如下   ,在最后一个命令被删除后,跳转命令不再执行


$ echo "this, is, a, test, to, remove, commas," | sed -n '{
:start
s/,//1p
/,/b start
}'
this is, a, test, to, remove, commas,
this is a, test, to, remove, commas,
this is a test, to, remove, commas,
this is a test to, remove, commas,
this is a test to remove, commas,
this is a test to remove commas,
this is a test to remove commas




测试    t  很好的结束跳出循环。




$ sed '{
> s/first/matched/
> t
> s/this is the/no match on/
> }' data1
no match on header line
this is the matched data line
no match on second data line
no match on last line






$ echo "this, is, a, test, to, remove, commas," | sed -n '{
:start
s/,//1p
t start
}'
this is, a, test, to, remove, commas,
this is a, test, to, remove, commas,
this is a test, to, remove, commas,
this is a test to, remove, commas,
this is a test to remove, commas,
this is a test to remove commas,
this is a test to remove commas





模式替换



$ echo "the cat sleep in this hat." |sed 's/cat/"cat"/'
the "cat" sleep in this hat.



$ echo "the cat sleep in this hat." |sed 's/.at/".at"/g'
the ".at" sleep in this ".at".



and符号


$ echo "the cat sleep in in his hat," | sed 's/.at/"&"/g'
the "cat" sleep in in his "hat",




替换单独的单词




$ echo "the system administrator manual" | sed '
> s/\(system\) administrator/\1 user/'
the system user manual



$ echo "that furry cat is pretty" | sed 's/furry \(.at\)/\1/'
that cat is pretty

$ echo "that furry hat is pretty" | sed 's/furry \(.at\)/\1/'
that hat is pretty


$ echo "1234567" | sed '{
> :start
> s/\(.*[0-9]\)\([0-9]\{3\}\)/\1.\2/
> t start
> }'
1.234.567



在脚本中使用sed



$ sh reserve data1

this is the last line
this is the second data line
this is the first data line
this is the header line
reserve:行9: $: 未找到命令



重定向sed的输出


$ cat data1
#!/bin/bash
#add commas to numbers in factorial answer

factorial=1
counter=1
number=$1

while [ $counter -le $number ]
do
        factorial=$[ $factorial * $counter ]
        counter=$[ $counter + 1 ]
done

result=`echo $factorial | sed '{
:start
s/\(.*[0-9]\)\([0-9]\{3\}\)/\1,\2/
t start

}'`

echo "the result is $result"
$


$ sh data1 20
the result is 2,432,902,008,176,640,000
data1:行22: $: 未找到命令






创建sed实用工具



 
加倍行间距   G : 在所有行后添加空白行



$ cat data1
this is the header line
this is the first data line
this is the second data line
this is the last line
$ sed 'G' data1
this is the header line

this is the first data line

this is the second data line

this is the last line






不把空白行加到最后一行


$ cat data1
this is the header line
this is the first data line
this is the second data line
this is the last line

$ sed '$!G' data1
this is the header line

this is the first data line

this is the second data line

this is the last line




对可能含有空白行的文件加倍行间距



$ cat data1
this is the header line
this is the first data line

this is the second data line
this is the last line



$ sed '$!G' data1
this is the header line

this is the first data line



this is the second data line

this is the last line

Administrator@MS-20170425YVKO ~




$ cat data1
this is the header line
this is the first data line

this is the second data line
this is the last line

$ sed '/^$/d;$!G' data1
this is the header line

this is the first data line

this is the second data line

this is the last line




给文件中的行编号



$ sed '/^$/d;$!G;'='' data1
1
this is the header line

2
this is the first data line

4
this is the second data line

5
this is the last line



$ cat data1
this is the header line
this is the first data line

this is the second data line
this is the last line

$ sed '=' data1
1
this is the header line
2
this is the first data line
3
this is the second data line
4
this is the last line



行号在数据流的左边---将换行符换成空格



$ cat data1
this is the header line
this is the first data line
this is the second data line
this is the last line

$ sed '=' data1 | sed 'N; s/\n/ /'
1 this is the header line
2 this is the first data line
3 this is the second data line
4 this is the last line



打印末尾行



$ cat data1
this is the header line
this is the first data line
this is the second data line
this is the last line

$ sed -n '$p' data1
this is the last line


D  : 删除模式空间的第一行
N  : 循环。




删除两行之间连续的空白行,留一个空白行


$ sed '/./,/^$/!d' data1    区间是/./,^$/!d


$ cat data1


this is the header line


this is the first data line

this is the second data line


this is the last line


$ sed '/./,/^$/!d' data1
this is the header line

this is the first data line

this is the second data line

this is the last line






删除开头的空白行



$ sed '/./,$!d' data1  


$ cat data1


this is the header line


this is the first data line

this is the second data line


this is the last line



$ sed '/./,$!d' data1
this is the header line


this is the first data line

this is the second data line


this is the last line





删除结尾的空白行



$ cat data1
this is the first data line

this is the second data line





Administrator@MS-20170425YVKO ~



$ sed '{
:start
/^\n*$/{$d; N; b start }
}' data1
this is the first data line

this is the second data line

Administrator@MS-20170425YVKO ~




删除HTML标签



错误命令  


$ cat data1
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="GBK" />
<title>优质品牌购物网站大全-皮皮爱购物</title>
this is the <b>first</i>


$ sed 's/<.*>//g' data1




this is the




正确命令   忽略原始标签中的大于号


$ cat data1
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="GBK" />
<title>优质品牌购物网站大全-皮皮爱购物</title>
this is the <b>first</i>



$ sed 's/<[^>]*>//g' data1



优质品牌购物网站大全-皮皮爱购物
this is the first


$ sed 's/<[^>]*>//g;/^$/d' data1     -删除空白行
优质品牌购物网站大全-皮皮爱购物
this is the first




gawk进阶阶段




变量


FS  输入字段分隔符

RS  输入数据行分隔符

OFS  输出字段分隔符
ORS  输出数据行分隔符



$ cat data1
data11,data12,data13,data14,data15

$ gawk 'BEGIN{FS=","} {print $1,$2,$3}' data1
data11 data12 data13



$ cat data1                           改变字符之间的符号
data11,data12,data13,data14,data15

$ gawk 'BEGIN{FS=",";OFS="-"} {print $1,$2,$3}' data1
data11-data12-data13
$ gawk 'BEGIN{FS=",";OFS="<->"} {print $1,$2,$3}' data1
data11<->data12<->data13



根据字段宽度进行分割



$ cat data1
1005.32456.37
115-2.349194.00

$ gawk 'BEGIN{FIELDWIDTHS=" 3 5 2 5"} {print $1,$2,$3,$4}' data1
100 5.324 56 .37
115 -2.34 91 94.00




FS RS 结合使用

$ cat data1
riley mullen
123 main street
chicago il 60601
(321)555-1234


rfriank williams
456 oak street
indianapolis,in 46201
(317)555-9876


haley snelll
4231 elm street
detroi.mi 455
(313)555-4983


$ gawk 'BEGIN{FS="\n";RS=""} {print $1,$4}' data1
riley mullen (321)555-1234
rfriank williams (317)555-9876
haley snelll (313)555-4983



数据变量



ARGC    当前命令行参数个数


ARGIND   当前文件在ARGV中的位置


ARGV     包含命令行参数的数组



CONVFMT     数字的转换格式


ENVIRON      当前shell环境变量以及其组成的关联数组


ERRNO      当读取或关闭输入文件发生错误时的系统错误号


FILENAME   用gawk输入数据的数据文件的文件名


FNR   当前数据文件的数据行数


IGNORECASE   设成非零值时,忽略gawk命令中出现的字符串的字符大小写


NR    已处理的输入数据行目


OFMT    数字的输入格式;默认%.6g


RLENGTH   由match函数所匹配的子字符串的长度


RSTART     由match函数所匹配的子字符串的起始位置






自定义变量




$ gawk 'BEGIN{
> testing="this is a test"
> print testing
> }'
this is a test


$ gawk '
> BEGIN{
> testing="this is a test"
> print testing
> testing=45
> print testing
> }'
this is a test
45




算数赋值

$ gawk 'BEGIN{X=4; X= X * 2 + 3; print X}'
11




在命令行上给变量赋值



$ cat script1
BEGIN{FS=","}
{print $n}

$ cat data1
data12,data22,data23


$ gawk -f script1 n=2 data1
data22

$ gawk -f script1 n=3 data1
data23



显示字符段+文字



$ cat data1
data12,data22,data23


$ cat script1
BEGIN{print "the starting value is",n; FS=","}
{print $n}

$ gawk -f script1 n=3 data1
the starting value is
data23


$ gawk -v n=3 -f script1 data1
the starting value is 3
data23



处理数组


定义数组变量


$ gawk 'BEGIN{
> capital["lips"] = "spring"
> print capital["lips"]
> }'
spring


$ gawk 'BEGIN{
var[1] = 34
var[2] = 3
total = var[1] + var[2]
print total
}'
37




遍历数组变量



$ gawk 'BEGIN{
> var["a"] = 1
>  var["g"] = 2
> var["m"] = 3
> var["u"] = 4
> for (test in var)
> {
> print "index:"test "- value:" var[test]
> }
> }'
index:u- value:4
index:m- value:3
index:a- value:1
index:g- value:2




删除数组变量


 正则表达式


$ cat data1
data12,data22,data23


$ gawk 'BEGIN{FS=","} /12/{print $1}' data1
data12



$ cat data1
data11,data12,data13,data23


$ gawk 'BEGIN{FS=","} $2 ~ /^data2/{print $0}' data1   空

Administrator@MS-20170425YVKO ~



$ gawk 'BEGIN{FS=","} $2 ~ /^data2/{print $0}' data1
data27,data26,data23,data24




数学表达式


$ cat data1
data27,data26,data23,data24


$ gawk -F, '$1 == "data26"{print $1}' data1

Administrator@MS-20170425YVKO ~

$ gawk -F, '$1 == "data27"{print $1}' data1
data27




结构化命令


$ cat data1
10
5
13
50
34


$ gawk '{if ($1 > 20) print $1}' data1
50
34


$ cat data1
10
5
13
50
34


$ gawk '{
> if ($1 > 20)
> {
> x = $1 * 20
> print x
> }
> }' data1
1000
680



支持if-else


$ gawk '{
> if ($1 > 20)
> {
> x = $1 * 20
> print x
> } else
> {
> x = $1 / 2
> print x
> }}' data1
5
2.5
6.5
1000
680



单行使用else


$ gawk '{if ($1 > 20) print $1 * 2;else print $1 / 2}' data1
5
2.5
6.5
100
68



while语句



$ cat data1
130 120 135
160 113 140
145 170 215

$ gawk '{
total = 0
i = 1
while (i < 4)
{
total += $i
i++
}
avg = total / 3
print "Average:" avg
}' data1
Average:128.333
Average:137.667
Average:176.667
Average:0



gawk支持break


$ gawk '{
> total = 0
> i = 1
> while (i < 4)
> {
> total +=$i
> if (i == 2)
> break
> i++
> }
> avg = total / 2
> print "the avetage of the first two data elements is :" avg
> }' data1
the avetage of the first two data elements is :125
the avetage of the first two data elements is :136.5
the avetage of the first two data elements is :157.5
the avetage of the first two data elements is :0




do-while语句


$ gawk '{
> total = 0
> i = 1
> do
> {
> total += $i
> i++
> } while (total < 150)
> print total }' data1
250
160
315





for 语句


$ gawk '{
> total = 0
> for (i=1;i<4;i++)
> {
> total += $i
> }
> avg = total / 3
> print "average:" avg
> }' data1
average:128.333
average:137.667
average:176.667
average:0




格式化输出


$ cat data2
Riley Mullen (312)555-1234
Frank Williams (317)555-9876
Haley Snell (313)555-4938

$ gawk 'BEGIN{FS="\n"; RS=""} {print $1,$4}' data2
Riley Mullen (312)555-1234


$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%s %s\n", $1,$4}' data2
Riley Mullen (312)555-1234

$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%16s %s\n", $1,$4}' data2
Riley Mullen (312)555-1234


$ gawk 'BEGIN{FS="\n"; RS=""} {printf "%-16s %s\n", $1,$4}' data2
Riley Mullen (312)555-1234















字符串函数


$ gawk 'BEGIN{
> var["a"] = 1
> var["g"] = 2
> var["m"] = 3
> var["u"] = 4
> asort(var,test)
> for (i in test)
> print "index:"i "- value:" test[i]
> }'
index:1- value:1
index:2- value:2
index:3- value:3
index:4- value:4



时间函数


$ gawk 'BEGIN{
date = systime()
day = strftime("%A,%B %d,%Y", date)
print day
}'
星期日,七月 02,2017



自定义函数




$ cat data2
Riley Mullen      - (312)555-1234
Frank Williams    - (317)555-9876
Haley Snell       - (313)555-4938


$ gawk '
function myprint()
{
print "%-16s - %s\n", $1,$4
}
BEGIN{FS="\n"; RS=""}
{
myprint()
}' data2
%-16s - %s
 Riley Mullen      - (312)555-1234







创建库函数




$ cat funclib
function myprint()
{
        printf "%-16s - %s\n", $1, $4
}
function myrand(limit)
{
        return int(limit * rand())
}
function printthird()
{
        print $3
}
$ cat script4
BEGIN{ FS="\n"; RS=""}
{
        myprint()
}

$ cat data2
Riley Mullen (312)555-1234
Frank Williams (317)555-9876
Haley Snell (313)555-4938

$ gawk -f funclib -f script4 data2
Riley Mullen (312)555-1234  -





使用其他shell


dash  shell


set   显示环境变量


$ cat test5
#!/bin/dash

value1=10
value2=15

value3=$(( $value1 * $value2 ))
echo "the answer is $value3"

 
$ sh test5
the answer is 150








function 命令



$ cat test10
#!/bin/dash
#testing functions

func1() {
        echo "this is an example of a function"
}

count=1
while [ $count -le 5 ]
do
        func1
        count=$(( $count + 1 ))
done
echo "this is the end of the loop"
func1
echo "this is the end of the script"

$ sh test10
this is an example of a function
this is an example of a function
this is an example of a function
this is an example of a function
this is an example of a function
this is the end of the loop
this is an example of a function
this is the end of the script





高级shell 脚本编程      ----------------492页



使用web





探索cURL



使用zsh处理网络



客户端、服务器模式


服务器程序


客户端程序






编写脚本使用工具


检测磁盘空间

$ du -s /home/*
1       /home/a.sh
171     /home/Administrator
1       /home/myfuncs
0       /home/testing


$ du -s /var/log/*
108     /var/log/setup.log
1896    /var/log/setup.log.full

$ du -S /var/log/*
108     /var/log/setup.log
1896    /var/log/setup.log.full


$ du -S /var/log/ | sort -rn
2004    /var/log/




$ du -S /var/log/ | sort -rn | sed '{11,$D; =}' | sed 'N; s/\n/ /' | gawk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'
1:      2004    /var/log/




创建脚本



#!/bin/dash
CHCEK_DIRECTORIES="/var/log /home"    #direction to check
######## main script ############
DATE=$(date '+%m%d%y')       

exec > disk_space_$DATE.rpt 

echo "top ten disk space usage"

echo "for $CHCEK_DIRECTORIES direction"

for DIR_CHECK in $CHCEK_DIRECTORIES
do
    echo ""
    echo "the $DIR_CHECK direction"
#creating a listing of top ten disk space users
du -S $DIR_CHECK 2>/dev/null |
sort -rn |
sed 'N; s/\n/ /' |
gawk '{printf $1 ":" "\t" $2 "\t" $3 "\n"}'

done



管理用户账户

 

posted @ 2018-11-24 16:32  effortsing  阅读(318)  评论(0编辑  收藏  举报