笔记:linux-sed[马哥linux]

sed

练习:写一个脚本 
判断当前系统上是否有用户的默认shell为bash; 
如果有,就显示有多少个这类用户;否则,就显示没有这类用户; 
grep "bash$" /etc/passwd &> /dev/null 
RETVAL=$? 
if [ $RETVAL -eq 0 ]; then 

if grep "bash$" /etc/passwd &> /dev/null; then 

提示:“引用”一个命令的执行结果,要使用命令引用;比如: RESAULTS=`wc -l /etc/passwd | cut -d: -f1`; 
使用一个命令的执行状态结果,要直接执行此命令,一定不能引用;比如: if id user1一句中的id命令就一定不能加引号; 
如果想把一个命令的执行结果赋值给某变量,要使用命令引用,比如USERID=`id -u user1`; 
如果想把一个命令的执行状态结果保存下来,并作为命令执行成功与否的判断条件,则需要先执行此命令,而后引用其状态结果,如 
id -u user1 
RETVAL=$? 
此句绝对不可以写为RETVAL=`id -u user1`; 


练习:写一个脚本 
判断当前系统上是否有用户的默认shell为bash; 
如果有,就显示其中一个的用户名;否则,就显示没有这类用户; 

练习:写一个脚本 
给定一个文件,比如/etc/inittab 
判断这个文件中是否有空白行; 
如果有,则显示其空白行数;否则,显示没有空白行。 
#!/bin/bash 
A=`grep '^$' /etc/inittab | wc -l` 
if [ $A -gt 0 ]; then 
echo "$A" 
else 
echo "meiyoukongbaihang" 
fi 
—— by 张帅 

#!/bin/bash 
FILE=/etc/inittab 
if [ ! -e $FILE ]; then 
echo "No $FILE." 
exit 8 
fi 

if grep "^$" $FILE &> /dev/null; then 
echo "Total blank lines: `grep "^$" $FILE | wc -l`." 
else 
echo "No blank line." 
fi 

练习:写一个脚本 
给定一个用户,判断其UID与GID是否一样 
如果一样,就显示此用户为“good guy”;否则,就显示此用户为“bad guy”。 
#!/bin/bash 
USERNAME=user1 
USERID=`id -u $USERNAME` 
GROUPID=`id -g $USERNAME` 
if [ $USERID -eq $GROUPID ]; then 
echo "Good guy." 
else 
echo "Bad guy." 
fi 

进一步要求:不使用id命令获得其id号; 

#!/bin/bash 

USERNAME=user1 
if ! grep "^$USERNAME\>" /etc/passwd &> /dev/null; then 
echo "No such user: $USERNAME." 
exit 1 
fi 

USERID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f3` 
GROUPID=`grep "^$USERNAME\>" /etc/passwd | cut -d: -f4` 
if [ $USERID -eq $GROUPID ]; then 
echo "Good guy." 
else 
echo "Bad guy." 
fi 






练习:写一个脚本 
给定一个用户,获取其密码警告期限; 
而后判断用户密码使用期限是否已经小于警告期限; 
提示:计算方法,最长使用期限减去已经使用的天数即为剩余使用期限; 

如果小于,则显示“Warning”;否则,就显示“OK”。 

圆整:丢弃小数点后的所有内容 

#!/bin/bash 
W=`grep "student" /etc/shadow | cut -d: -f6` 
S=`date +%s` 
T=`expr $S/86400` 
L=`grep "^student" /etc/shadow | cut -d: -f5` 
N=`grep "^student" /etc/shadow | cut -d: -f3` 
SY=$[$L-$[$T-$N]] 

if [ $SY -lt $W ]; then 
echo 'Warning' 
else 
echo 'OK' 
fi 

—— by 董利东 


练习:写一个脚本 
判定命令历史中历史命令的总条目是否大于1000;如果大于,则显示“Some command will gone.”;否则显示“OK”。 


shell中如何进行算术运算: 
A=3 
B=6 
1、let 算术运算表达式 
let C=$A+$B 
2、$[算术运算表达式] 
C=$[$A+$B] 
3、$((算术运算表达式)) 
C=$(($A+$B)) 
4、expr 算术运算表达式,表达式中各操作数及运算符之间要有空格,而且要使用命令引用 
C=`expr $A + $B` 



条件判断,控制结构: 

单分支if语句 
if 判断条件; then 
statement1 
statement2 
... 
fi 

双分支的if语句: 
if 判断条件; then 
statement1 
statement2 
... 
else 
statement3 
statement4 
... 
fi 

多分支的if语句: 
if 判断条件1; then 
statement1 
... 
elif 判断条件2; then 
statement2 
... 
elif 判断条件3; then 
statement3 
... 
else 
statement4 
... 
fi 



测试方法: 
[ expression ] 
[[ expression ]] 
test expression 

bash中常用的条件测试有三种: 
整数测试: 
-gt 
-le 
-ne 
-eq 
-ge 
-lt 

INT1=63 
INT2=77 
[ $INT1 -eq $INI2 ] 
[[ $INT1 -eq $INT2 ]] 
test $INT1 -eq $INT2 

文件测试:
-e FILE:测试文件是否存在 
-f FILE: 测试文件是否为普通文件 
-d FILE: 测试指定路径是否为目录 
-r FILE: 测试当前用户对指定文件是否有读取权限; 
-w 
-x

[ -e /etc/inittab ] 
[ -x /etc/rc.d/rc.sysinit ]

练习:写一个脚本 
给定一个文件: 
如果是一个普通文件,就显示之; 
如果是一个目录,亦显示之; 
否则,此为无法识别之文件; 



定义脚本退出状态码 

exit: 退出脚本 
exit # 
如果脚本没有明确定义退出状态码,那么,最后执行的一条命令的退出码即为脚本的退出状态码; 


测试脚本是否有语法错误: 
bash -n 脚本 

bash -x 脚本:单步执行 



bash变量的类型: 
本地变量(局部变量) 
环境变量 
位置变量: 
$1, $2, ... 
shift 
特殊变量: 
$? 
$#:参数的个数 
$*: 参数列表 
$@:参数列表 

./filetest.sh /etc/fstab /etc/inittab 
$1: /etc/fstab 
$2: /etc/inittab 

练习:写一脚本 
能接受一个参数(文件路径) 
判定:此参数如果是一个存在的文件,就显示“OK.”;否则就显示"No such file." 

练习:写一个脚本 
给脚本传递两个参数(整数); 
显示此两者之和,之乘积; 
#!/bin/bash 

if [ $# -lt 2 ]; then 
echo "Usage: cacl.sh ARG1 ARG2" 
exit 8 
fi 

echo "The sum is: $[$1+$2]." 
echo "The prod is: $[$1*$2]." 


练习:写一个脚本,完成以下任务 
1、使用一个变量保存一个用户名; 
2、删除此变量中的用户,且一并删除其家目录; 
3、显示“用户删除完成”类的信息; 





bash: 

引用变量:${VARNAME}, 括号有时可省略。 




整型,8bit: 256 
0-255, 溢出 


变量: 
1,10000 


10:16bit 
10: 1010, 8bit 


编程能力: 
脚本编程 


grep, sed(流编辑器), awk 

sed基本用法: 
sed: Stream EDitor 
行编辑器 (全屏编辑器: vi) 

sed: 模式空间 
默认不编辑原文件,仅对模式空间中的数据做处理;而后,处理结束后,将模式空间打印至屏幕; 


sed [options] 'AddressCommand' file ... 
-n: 静默模式,不再默认显示模式空间中的内容 
-i: 直接修改原文件 
-e SCRIPT -e SCRIPT:可以同时执行多个脚本 
-f /PATH/TO/SED_SCRIPT 
sed -f /path/to/scripts file 
-r: 表示使用扩展正则表达式 

Address: 
1、StartLine,EndLine 
比如1,100 
$:最后一行 
2、/RegExp/ 
/^root/ 
3、/pattern1/,/pattern2/ 
第一次被pattern1匹配到的行开始,至第一次被pattern2匹配到的行结束,这中间的所有行 
4、LineNumber 
指定的行 
5、StartLine, +N 
从startLine开始,向后的N行; 

Command: 
d: 删除符合条件的行; 
p: 显示符合条件的行; 
a \string: 在指定的行后面追加新行,内容为string 
\n:可以用于换行 
i \string: 在指定的行前面添加新行,内容为string 
r FILE: 将指定的文件的内容添加至符合条件的行处 
w FILE: 将地址指定的范围内的行另存至指定的文件中; 
s/pattern/string/修饰符: 查找并替换,默认只替换每行中第一次被模式匹配到的字符串 
加修饰符 
g: 全局替换 
i: 忽略字符大小写 
s///: s###, s@@@
\(\), \1, \2 

l..e: like-->liker 
love-->lover 

like-->Like 
love-->Love 

&: 引用模式匹配整个串 

sed练习: 
1、删除/etc/grub.conf文件中行首的空白符; 
sed -r 's@^[[:spapce:]]+@@g' /etc/grub.conf 
2、替换/etc/inittab文件中"id:3:initdefault:"一行中的数字为5; 
sed 's@\(id:\)[0-9]\(:initdefault:\)@\15\ 2@g' /etc/inittab 
3、删除/etc/inittab文件中的空白行; 
sed '/^$/d' /etc/inittab 
4、删除/etc/inittab文件中开头的#号; 
sed 's@^#@@g' /etc/inittab 
5、删除某文件中开头的#号及后面的空白字符,但要求#号后面必须有空白字符; 
sed -r 's@^#[[:space:]]+@@g' /etc/inittab 
6、删除某文件中以空白字符后面跟#类的行中的开头的空白字符及# 
sed -r 's@^[[:space:]]+#@@g' /etc/inittab 
7、取出一个文件路径的目录名称; 
echo "/etc/rc.d/" | sed -r 's@^(/.*/)[^/]+/?@\ 1@g'
基名: 
echo "/etc/rc.d/" | sed -r 's@^/.*/([^/]+)/?@\ 1@g'

#abc 
# hello world 
# hi world 



练习: 
传递一个用户名参数给脚本,判断此用户的用户名跟其基本组的组名是否一致,并将结果显示出来。 



字符测试: 
==:测试是否相等,相等为真,不等为假 
!=: 测试是否不等,不等为真,等为假 


-n string: 测试指定字符串是否为空,空则真,不空则假 
-z string: 测试指定字符串是否不空,不空为真,空则为假 

练习:写一个脚本 
传递一个参数(单字符就行)给脚本,如参数为q,就退出脚本;否则,就显示用户的参数; 

练习:写一个脚本 
传递一个参数(单字符就行)给脚本,如参数为q、Q、quit或Quit,就退出脚本;否则,就显示用户的参数; 
#!/bin/bash 

if [ $1 = 'q' ];then 
echo "Quiting..." 
exit 1 
elif [ $1 = 'Q' ];then 
echo "Quiting..." 
exit 2 
elif [ $1 = 'quit' ];then 
echo "Quiting..." 
exit 3 
elif [ $1 = 'Quit' ];then 
echo "Quiting..." 
exit 4 
else 
echo $1 
fi 


练习: 
传递三个参数给脚本,第一个为整数,第二个为算术运算符,第三个为整数,将计算结果显示出来,要求保留两位精度。形如: 
./calc.sh 5 / 2 

练习: 
传递3个参数给脚本,参数均为用户名。将此些用户的帐号信息提取出来后放置于/tmp/testusers.txt文件中,并要求每一行行首有行号。 


写一个脚本: 
判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor id一行中。 
如果其生产商为AuthenticAMD,就显示其为AMD公司; 
如果其生产商为GenuineIntel,就显示其为Intel公司; 
否则,就说其为非主流公司; 


写一个脚本: 
给脚本传递三个整数,判断其中的最大数和最小数,并显示出来。 
MAX=0 
MAX -eq $1 
MAX=$1 
MAX -lt $2 
MAX=$2 




循环:进入条件,退出条件 
for 
while 
until 

for 变量 in 列表; do 
循环体 
done 

for I in 1 2 3 4 5 6 7 8 9 10; do 
加法运算 
done 

遍历完成之后,退出; 

如何生成列表: 
{1..100} 
`seq [起始数 [步进长度]] 结束数` 


1,...,100 

declare -i SUM=0 
integer 
-x 



写一个脚本: 
1、设定变量FILE的值为/etc/passwd 
2、依次向/etc/passwd中的每个用户问好,并显示对方的shell,形如: 
Hello, root, your shell: /bin/bash 
3、统计一共有多少个用户 

for I in `seq 1 $LINES`; do echo "Hello, `head -n $I /etc/passwd | tail -1 | cut -d: -f1`"; done 

只向默认shell为bash的用户问声好 


写一个脚本: 
1、添加10个用户user1到user10,密码同用户名;但要求只有用户不存在的情况下才能添加; 

扩展: 
接受一个参数: 
add: 添加用户user1..user10 
del: 删除用户user1..user10 
其它:退出 
adminusers user1,user2,user3,hello,hi 



写一个脚本: 
计算100以内所有能被3整除的正整数的和; 
取模,取余:% 
3%2=1 
100%55=45 

写一个脚本: 
计算100以内所有奇数的和以及所有偶数的和;分别显示之; 

let I=$[$I+1] 
SUM=$[$SUM+$I] 

let SUM+=$I 

let I+=1 相当于 let I++ 

-= 
let I-=1 相当于 let I-- 

++I, --I 

*= 
/= 
%= 



写一个脚本,分别显示当前系统上所有默认shell为bash的用户和默认shell为/sbin/nologin的用户,并统计各类shell下的用户总数。显示结果形如 
: 
BASH,3users,they are: 
root,redhat,gentoo 

NOLOGIN, 2users, they are: 
bin,ftp 


#!/bin/bash 

NUMBASH=`grep "bash$" /etc/passwd | wc -l` 
BASHUSERS=`grep "bash$" /etc/passwd | cut -d: -f1` 
BASHUSERS=`echo $BASHUSERS | sed 's@[[:space:]]@,@g'` 

echo "BASH, $NUMBASH users, they are:" 
echo "$BASHUSERS 







在剩下的三月里,你愿意与学习结为伴侣,无论贫穷还是富贵,无论电脑还是手机,无论多困或者多累,无论想吃还是想睡,都要把学习放在第一位 
,以不落后为目标,同甘共苦同舟共济永不言弃,爱惜她尊重她理解她保护她,你愿意这样做么? 

Yes,I do! 


测试: 
整数测试 
-le 
-lt 
-ge 
-gt 
-eq 
-ne 
字符测试 
== 
!= 


-n 
-z 
文件测试 
-e 
-f 
-d 
-r 
-w 
-x 

if [ $# -gt 1 ]; then 

组合测试条件 
-a: 与关系 
-o: 或关系 
!: 非关系 

if [ $# -gt 1 -a $# -le 3 ] 
if [ $# -gt 1 ] && [ $# -le 3 ] 

q, Q, quit, Quit 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值