admin 管理员组文章数量: 887239
2024年1月18日发(作者:windows7怎么升级10)
非正常退出时的文件恢复:
1.非正常退出后再次登录执行vim /test时,会出现这样的界面提示:
2.执行vim -r test后再次执行vim /test时,出现下面的提示界面:
3.未删除.文件时,即使恢复了文件仍然提示,恢复并删除才算完成:
1
nower 365制作
环境变量:
2
nower 365制作
grep(基本型)
参数:
^ 匹配行首
$ 匹配行尾
. 匹配单字符
* 在正则表达式中表示匹配 >= 0 个前面出现的字符,而在bash中*表示>=0个任意字符
[] 里面可以写很多,但是值匹配一个,如果都找到呢,就都输出来
转义符,如 ’.$’ 表示以 . 结尾
grep –v ‘12’ /share/date 在/share/date中找不含12的行,只要有12的行就不显示。但是grep ‘【^2】’ /share/date表示非2的的都可以显示,如果这一行的内容只有23,那么3是符合条件的,仍然显示这一行。区别很微妙,操作一下就明白了……
^$空行
^…$只有3个字符的行
^.*$匹配行中任意字符
.* 用的非常多的,匹配任意个任意种类的字符(即>=0个),比如找到am和bm之间有任意多个任意字符时,用’am.*bm’,可以找到找到ambm,amhbm,amfsbm,……总之am与bm之间有>=0个字符就是了。另外am和bm之间有任意多个字符o时,用’amo*bm’,(不是amo.*bm哦),可以找到ambm,amobm,amoobm,amooobm……如果是在h和g之间有至少2个o呢,就是’ hooo*g’,找到3
nower 365制作
hoog,hooog,foooog……有点小啰嗦~~~
-i 不区分大小写,如 -i ‘the’ 就可以找到不区分大小写的the
o{a,b}既然功能相似就一起吧,这个表示匹配的次数,如果在h
和g之间有2个o就是 ’ho{2}g’,如果至少2就是 ’ho{2,}g’ ,
如果是2到5个呢,就是’ho{2,5}g’ 啦……
[IiNn]大写或小写i或n,但是[Ii][Nn]只能找到i和n,为什么,下图。
[^0-9a-zA-Z] 非数字且非字母
grep ‘12[0-3]’ /share/date 找含120或121或122或123,都存在呢,就都显示出来呗~~~
grep ‘^[^12]’ /share/date 查找开头不是12的行
grep ‘[Ss]tep’ 找Step或step
grep –E ‘134 | 159’ /share/test 找134或159,用管道符号时必须加 –E ,因为grep是基本型的,如果是延伸型的egrep就不用加
-E啦,所以只用grep ‘134 | 159’ /share/test会找不到。但是为什么用egrep ‘134 | 159’ /share/test找到了,却没有行号和颜色呢,因为提前已经在~/.bashrc设置好了alias grep = ‘ grep -n
--color=auto ’ ,加入这条语句后执行source ~/.bashrc重启终端生效,或者关掉终端再打开。
4
nower 365制作
egrep(延伸性)
egrep是grep的延伸,它有更多的功能,主要表现在上面提到的管道符号上,另外还有一些……
如果想去掉以#开头的注释行和空白行,用基本型grep表示为
grep –v ‘^#’ /share/test | grep –v ‘^$’
用延伸型的egrep表示为
egrep -v ‘^#|^$’ /share/test
这样看区别很明显吧!!!
‘go?d’ g和d之间有0个或1个o,即gd或god
‘go+d’ g和d之间有 >=1个o,即god或good或goood……
‘go*d’ g和d之间有 >=0个o,即gd或god或good或goood……
‘go.*d’ go和d之间有 >=0个任意字符,即god或gohd或gostd……
‘g(oo|la)d’ 找good或glad,注意grep中用(),而grep用[]
‘A(xyz)+W’ 找开头是A结尾是W,中间有>=1个字符串xyz,如xyz,xyzxyz……例如执行echo ‘AxyzxyzxyzxyzW’ |egrep ‘A(xyz)+W’
5
nower 365制作
Sed: 查找工具,查找或替换一个文件中的指定行,是面向行的操作,但是用字符串替换命令却可以直接对行中的字符串替换,(如果就爱了个指定字符串替换为空就删掉了)所以sed可以插入,删除行,也可以插入,删除字符串。但是不会对原文件修改,只是将结果输出
参数:
a 在指定行的后面插入一行
i 在指定行的前面插入一行
(如果插入几行呢,就在各行之间用换行符n)
d 删除指定的一行或几行
p 在屏幕列出指定的一行或几行,常与-n配合使用
c 面向行的操作,替代一行或几行 (将几行替代为一行或将一行替代为几行都可以)
sed ‘s/this/that/g’ 替换字符串命令 将this替换为that,是面向指定行中的指定字符串的操作。有了它sed变得更强大了,它将sed的行操作扩展到行中的字符串,可以插入、替换或删除字符串,和vim中命令行模式下的 :$s/this/that/g类似,但是更好用。
-i 直接修改文档内容而不输出,慎用。如:sed -i ‘s/ .$ / ! /g’可将每行末尾的 . 替换为 !(.和!都加了转义符) 。注意这个 -i和上面的i有所不同。
例子:
下面的4个小技巧是在文档中操作的:
6
nower 365制作
Sed ‘2,$d’ 删除第二行到最后一行
Sed’$d’ 删除最后一行
如果有一行内容为 a is b 那么怎么来插入和删除呢
Sed ‘s/is/is from/g’ 就插入了from了 变成a is from b
Sed ‘s/is//g’ 就删除is了,变成 a b
① nl /etc/passwd | sed ‘2a helllo n jim’
将hello 和jim两行插入到第二行的后面,注意helllo和jim之间加了换行符 n哦
② 将a替换为i就是插入到第二行的前面
③ nl /etc/passwd |sed ‘2,5 d’ 删除2,3,4,5行
④ nl /etc/passwd | sed -n ‘5,7 p’ 在屏幕输出5,6,7行,与-
-n一起用
⑤ nl /etc/passwd | sed ‘ 2,30c helllo n jim’ 将2到30行换为helllo7
nower 365制作
和jim两行
⑥ /sbin/ifconfig eth0 | grep’inet addr’ 可找到含inet addr: 的行。
/sbin/ifconfig eth0 | grep’inet addr’ | sed ’s/^.*addr://g’ |
sed ’s/Bcast.*$//g ’ 先将 addr: 及前面的内容换为空(即删除),再将Bcast后面的内容换为空(删除),结果呢,这一行就只剩192.168.0.10了,这就是替换的强大之处,如下图(如果将指定字符串替换为其他呢)
⑦ cat /etc/ | grep ‘MAN’ | sed ‘s/^#.*//g’ | sed’s/^$//g’用grep找到含MAN的行,再在其中将以#开头的注释行换为空行,再将空行删除。(注意是换为空行,所以原来的注释行虽然内容没有了,但是行还在,也就是出现了许多空行,所以后面才删除空行) 其中以#开头的注释行除了用^#.*表示,也可以用#.*$表示。 上面的方法虽然能涉及更多的知识点,却很繁琐,不如直接将以#开头的注释行删除,命令为:
cat /etc/ | grep ‘MAN’ | sed ‘/^#.*/ d’
d表示删除,以#开头的注释行用/^#.*/表示,注意加两个/哦
8
nower 365制作
awk:
以行为单位,面向列的处理工具。
NF: Now Field 每一行的列数(字段数)
NR:Now Row 目前awk处理的是第几行
FS: string 分隔符,不设置则默认是空格
逻辑符号: > < == >= <= !=
例子:
(1) last -n 5 | awk ‘{print $1 “t” $3 }’ 先列出前5行,再打印输出 第一和第三列,并用tab分隔
(2) cat /etc/passwd | awk ‘BEGIN{FS=”:”} $3<10{print $1 “t” $3}’
如果第三列值小于10就将第1和第3列输出,加BEGIN使分隔符:在第一列就生效,否则在第二列生效且从第二列开始输出
(3)last -n 5|awk ‘{print $1 “t lines:” NR “t columes:” NF }’
执行结果为:
root lines:1 columes:10
root lines:2 columes:10
nower lines:3 columes:10
……
(4)Cat | awk ’NR==1
{printf ”%10s %10s %10s %10s %10s n” , $1, $2, $3, $4, ”Total” }
9
nower 365制作
NR>=2{total=$2+$3+$4;printf “%10s %10d %10d %10d %10.2fn” ,
$1,$2,$3,$4,total}’
执行结果为:
Name first second third Total
Jim 10 20 30 60.00
Tom 1 2 3 6.00
Jim 5 2 4 11.00
原文件为:
Name first second third
Jim 10 20 30
Tom 1 2 3
Jim 5 2 4
格式: awk ‘条件1{动作1} 条件2{动作2} ……’ 文件名
注意:所有条件和动作在单引号中,printf中的内容用双引号而不是单引号,变量值不加双引号,多个动作用分号隔开
修改登录shell
方法一:永久修改。在/etc/paswd中将smb用户的shell由bash该为csh,然后切到smb用户,用echo $version查看,发现已经改为tcsh,如下图:
10
nower 365制作
方法二:永久修改。直接执行chsh(即change shell),然后写下想要的shell类型,再执行chsh时可以看见已经改了,下图:
下面的所有test文件都需要修改权限才能执行:chmod +x 文件名
Test0:
#!/bin/bash
#test
echo -e "this 3 linesnnn"
echo "ok"
echo "enter your name:n" #这一行的输出前面没有加参数 -e ,所以不能换行,换行命令n被输出
read name
echo -e "enter your passwd:n"
read passwd
echo "name: $name,passwd:$passwd"
11
nower 365制作
Test1:
#!/bin/bash
#test1
myvar=80
echo "the value of var is:$myvar"
echo 'the value of var is:$myvar'
Test2:
#!/bin/bash
#test2
12
nower 365制作
for char in a b c d e
do
echo $char
done
Test3:
#!/bin/bash
#test3
for char in {1..5}
do
echo $char
done
Test4:
#!/bin/bash
#test4
for char in `ls /home`
13
nower 365制作
(可以写成 $(ls /home) 和用反单引号写成的`ls /home`
都是执行 ls /home 命令)
do
echo $char
done
Test5:
#!/bin/bash
#test5
i=0
while [ $i -lt 5 ]
do
echo “vlue of i is: $i”
i=$(($i+1)) (可写为i=`ecpr $i
done
14
+ 1` 注意反向单引号)
nower 365制作
Test6:
#!/bin/bash
#test5
echo $1
echo $2
echo $3
(前两行是注释,只为增加可读性,可以修改,数字只能是1到9)
Test7:
#!/bin/bash
#test7
read list
15
nower 365制作
for var in $list
do
echo $var
done
Test8:
#!/bin/bash
#test8
max=0
echo “please input number:”
read list
for var in $list
do
16
nower 365制作
if [ var -gt $max ]
then
max=$var
fi
done
echo “max number is:$max ”
Test9:
#!/bin/bash
#test9
echo”please input number :n”
17
nower 365制作
read actual
if [ $actual -ge 0 -a $actual -lt 80 ]
then
echo “your grade is C!”
elif [ $actual -ge 80 -a $actual -lt 90 ]
then
echo “ your grade is B!”
elif [ $actual -ge 90 -a $actual -le 100 ]
then
echo “ your grade is A!”
else
echo -e “your number is wrong !nplease
number:n”
fi
18
input next
nower 365制作
Test10:
#!/bin/bash
#test10
echo -e "please input your choice:n"
read choice
case $choice in
19
nower 365制作
1) echo "your choice is A" ;;
2) echo "your choice is B" ;;
3) echo "your choice is C" ;;
4) echo "your choice is D" ;;
5) echo "your choice is E" ;;
*) echo "your choice is wrong!" ;;
esac
Test11:
#!/bin/bash
#test11
echo -e "please input information:n Student name:"
read name
echo -e "Email Adddress:"
read email
20
nower 365制作
echo -e "Telephone number:"
read tel
echo -e "Student name:$namenEmail Adddress:$emailnTelephone
number:$teln" >> cc
最后一行代码改为 echo "$name:$email:$tel" >> cc
则文件cc的内容更新为:
执行界面:
21
nower 365制作
Test12:
#!/bin/bash
#test12
echo "The name of this programe is $0"
echo "There are totally $# parameters passed to this programe"
echo "The parameters are $*"
echo "The result is $?"
可以用 bash filename 来执行文件:
Test13:
#!/bin/bash
#test13
if test $# -eq 0
then
echo "You should specify a file!"
22
nower 365制作
else
gzip $1
mv $ $HOME/dustbin
echo -e "File $1 is deleted to the dustbinnyou can pick it up as you
"
fi
这是一个简单的把文件删除到垃圾箱的脚本,垃圾箱就是用户目录下的一个dustbin目录,$HOME可以通配所有的用户目录,即在smb用户的时候相当于/home/smb。脚本有问题,当不存在文件时,仍然会执行else下的命令并输出最后一行的提示,这是因为判断条件不合理,$# -eq 0表示自行脚本时文件名后的字符不为空就执行else语句。
Test14:
#!/bin/bash
#test14
for i in $HOME/dustbin/*.gz
23
nower 365制作
do
rm -f $i
echo "$i has been deleted forever!"
done
这是一个把垃圾箱里的文件彻底删除的脚本
Test15:
#!/bin/bash
#test15
function test15()
{
re=0
num=0
while [ $num -lt 10 ]
#或写 while [ $num -lt 10 ]
do
24
nower 365制作
num=`expr $num + 1`
re=`expr $re + $num`
done
return $num
}
test15
echo "num=$num"
echo "result = $re"
这段脚本实现1+2+…+10,可以不用功能函数实现
Test16:
#!/bin/bash
#test8
echo "Please input a number:"
read num
n=1
25
nower 365制作
while [ $n -le $num ]
do
i=1
while [ $i -le $n ]
do
printf "*"
i=$(($i+1))
done
printf "n"
n=$(($n+1))
done
把*改为$i:
把*改为$n
26
nower 365制作
Test17:
这是一个备份文件的脚本:
#!/bin/bash
#test17: a scripts of back files(运行时在后面输入要备份的文件)
LOG_START_TIME=`date +"%Y%m%d%H%M%S"` #时间格式,是写在备份日志文件名和日志里面的
BACKUP_DIR=/share/backup #备份目录,是备份文件的存放位置
BACKUP_LOG="${BACKUP_DIR}/${LOG_START_TIME}.log" #备份日志,是备份目录下的一个以时间为名称后缀为.log的文本
function write_log()
{
log_time=`date +"%Y-%m-%d-%H-%M-%S"` #时间格式,是输出到屏幕上的
backup_file_name=$2
#执行脚本时在命令行输入 ./test17 test test1 test2 test3 test4
其中 ./test17的位置是$1,test的位置是 $2,test1的位置是$3,脚本执行时是一个一个的备份的,当位置$2的test备份完后,$3上的test1向左移动到$2的位置,这时$2位置不再是test而变成test1,27
nower 365制作
所以脚本中用$2来表示其实是一种循环,每备份一个文件就输出到屏幕一次并写一个备份日志,然后在备份$2位置上新的文件,直到完成所有备份循环才结束,所以看到屏幕上输出备份结果时,两个输出之间会有一个短暂的停顿,因为备份每一个文件都需要一个短暂的时间。
err_msg="$log_time ERROR in backup
file/directory($backup_file_name)"
#备份出错时的打印输出
suc_msg="$log_time SUCCESS in backup
file/directory($backup_file_name)"
#备份成功时的打印输出
if [ $1 -eq 0 ];then
echo $suc_msg
echo $suc_msg >> $BACKUP_LOG
else
echo $err_msg
echo $err_msg >> $BACKUP_LOG
fi
}
function backup_file()
{
cp -rf $1 $BACKUP_DIR > /dev/null 2>$1
28
nower 365制作
write_log $? $1
}
function create_log_file()
{
if [ ! -e $BACKUP_DIR ];then
mkdir $BACKUP_DIR
fi
if [ -e $BACKUP_LOG ];then
rm -f $BACKUP_LOG
fi
touch $BACKUP_LOG
}
clear #脚本执行时先清屏再输出
echo "Backup "
create_log_file #调用函数
for file in $* #或写$@
do
backup_file $file
done
echo "Backup Process Ends!"
29
nower 365制作
执行脚本之前/share的内容:
执行下面的命令:
执行后的界面如下,注意目录/home不能被备份:
执行脚本后的/share目录有一个backup文件夹,且里面有:两个文件和一个以时间命名的日志:
30
nower 365制作
31
nower 365制作
版权声明:本文标题:shell高级编程经典教程 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/free/1705530303h488730.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论