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
数学运算
1、expr 基本不能用
$ 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
管理用户账户