20150913-0915 shell,sed,awk

一、作业(练习)内容:

1、描述shell程序的运行原理(可附带必要的图形说明);

shell的解释:

Shell的作用是linux操作系统的外壳,为用户提供使用操作系统的接口。它是命令语言、命令解释程序及程序设计语言的统称。

Shell会先确认用户的词语分析,来理解命令,选项,参数来进行解析。Shell中有内建命令,还有外部命令;流程的过如下:

(1)读取用户由键盘输入的命令;

(2)分析语法,命令,参数,然后配置参数;

(3)终端进程调用fork( )建立一个子进程;

(4)进程创建完成后,内部运行的指令提交给内核来完成任务;

(5)代码执行结束后,进程通知shell,它的任务已完成,子进程中止;

(6)shell接到退出指令,将显示下一个提示符,等待接受下一条命令;

2、总结shell编程中所涉及到的所有知识点(如:变量、语法、命令状态等等等,要带图的哟);

shell 的变量:

Shell中的变量的意思就是可变化的量,程序运行到进程以后再内存中申请的内存空间,这个空间可以反复存储与修改数据,另外也可命名的存储空间。

变量的分类:

本地变量:

只对当前shell进程有效的变量,对其他shell进程无效,包括当前shell进程的子进程。

定义本地变量: VAR_NAME=VALUE

变量名:包含数字,字母和下划线,且不能以数字开头;

变量赋值:向变量的存储空间保存数据;

变量引用:${VAR_NAME}

“”:弱引用,里面的变量会被替换;

‘’:强引用,里面的所有祖父都是字面量,直接输出;

声明数值类型:

declare -i name{=value}

实例:强引用,弱引用,以及定义的方法:

环境变量:

对当前shell进程及其子shell有效,对其他shell进程无效。

定义环境变量: export VAR_NAME=VALUE

导出: export VAR_NAME

查看环境变量:env ,printenv,export

添加PATH环境变量,第1种方法:(用户注销就失效)

[[email protected]_web_s1 ~]# export PATH=/usr/local/webserver/mysql/bin:$PATH

第2种方法:

# vim /etc/profile

在最后,添加:

export PATH="$PATH:/tmp/hzm/"

保存,退出,然后运行:

#source /etc/profile

局部变量:

对shell脚本中某代码片段有效,通常用于函数本地:

定义局部变量:Loacl export VAR_NAME=VALUE

位置参数与特殊变量:

$#:传递给脚本的参数数量;

$0 脚本的名称;

$1,$2,$3.... 第一个参数,第二个参数,第三个参数;

[email protected] :所有参数的列表;

实例:用脚本输出方式展现各参数的意义:

语法:

1. 第一行必须是"#!/bin/sh"

#!/bin/sh"是对shell的声明,说明你所用的是那种类型的shell及其路径所在;

如果没有声明,则脚本将在默认的shell中执行,默认shell是由用户所在的系统定义为执行shell脚本的shell.

2.注释:开头为#

3.脚本内容:

实例:语法开头,#为注释内容,下面是脚本内容:

bash -n 检查脚本是否有语法错误

bash -x 显示脚本执行过程

命令状态:

0 :成功执行:检查、/etc/passwd目录是否存在,如果存在状态值返回0

非0 : 执行过程中出现异常或非正常退出;(状态值可以在脚本中作为结束脚本来使用)

$? 可以查看 最后一条命令的返回值 该变量可以在shell 脚本中的任何地方使用.

测试表达式:

[ EXPRESSION ]

整数测试:隐含做数值大小比较,所以不要给变量引用加引号;

实例:先定义变量:A=4,B=6

A -gt B 是否大于(echo $? 返回为1的状态为否定的,所以A不大于B)

A -ge B是否大于等于

A -lt B 是否小于

A -le B是否小于等于

A -eq B 是否等于

A -ne B 是否不等于

字符串比较:ASCII数值越大,所以相同的字母值越大;

> 是否大于

< 是否小于

== 是否等于:$A == $B

!= 是否不等于

-z 测试是否为空:空着为真,否则为假

-n 测试是否不空:不空为真,否则为假

文件测试:($? 为0存在,1则不存在)

-e:是否存在并且为文件存在:

-f:是否存在并且为普通文件:

-d 是否存在并且为目录

-h:是否存在并且为链接文件

-L:同上

-b:是否为块设备文件

-c:是否存在并且为字符设备文件

-S 是否存在并且为套接字文件

-p:是否存在且为管道文件

读写权限检测:

-r:当前用户是否拥有读权限

-w:当前用户是否拥有写权限

-x:当前用户是否拥有执行权限

-u:当前用户是否拥有suid权限

-k:文件是否拥有sticky权限

-g:文件是否有sgid

-O:当前用户是否为指定的属主

-G:当前用户是否为指定的属组

双目操作

A -nt B:是否晚于

A -ot B:A是否旧于B

A -ef B:是否指向同一个文件的硬链接

算数运算方式:

1.$[$A+$B]

2.$(($A+$B))

3.Let variable=$A+$B

4.expr $A + $B

3、总结课程所讲的所有循环语句、条件判断的使用方法及其相关示例;(if (jpg|png is not exist);echo ”You say a XX“)

if语句结构

单分之if:

if then,
if true-分支
fi

if:

实例:如果用户root存在,则输出该用户存在;

双分支if:

if then,
if true分支
else
if false分支
fi
if

实例:如果该用户存在,输出user存在,否则该用户不存在;

多分支if语句:

if
elif  ;then 
fi

实例:给脚本两个参数判断 a 与b的比较:

#!/bin/bash
read -p "please give two number:" a b
if [ $a -eq $b ]
then
   echo "$a is equal to $b"
elif [ $a -gt $b ]
then
   echo "$a is greater than $b"
elif [ $a -lt $b ]
then
   echo "$a is less than $b"
else
   echo "please give two number"
fi

for循环

for 变量 in LIST;do

循环体

done

LIST:是有一个或多个空格分隔开的字符串组成;把列表的值逐一赋值给变量;

实例1:在/tmp目录下创建1-10目录;

#!/bin/bash
for i in $( seq 1 10 );do
   mkdir -p /tmp/${k}
done

实例2:for循环嵌套,创建文件,创建1-10个目录,并且每个文件里面创建1-10个目录

#!/bin/bash
for k in $( seq 1 10 );do
   mkdir -p /tmp/aaa${k}
      for l in $( seq 1 10 );do
      mkdir -p /tmp/aaa$[k]/bbb${l}
    done
done

结果:

实例3:计算数值的特殊用法

#!/bin/bash
read -p "please give number:" s1
declare -i sum=0
for ((i=1;i<=$s1;i++));do
        sum=$[$i+$s1]
done
echo "the number:$sum"

结果:

组合判断:&& ||

cmd1 && cmd2 : 如果cmd1执行完毕而且正确,则开始执行cmd2

如果cmd1执行完毕且错误,则cmd2不执行

cmd1 || cmd2 :如果cmd1执行完毕且正确,则cmd2不执行

如果cmd1执行完毕错误,则开始执行cmd2

实例:若文件目录存在则创建123文件:

若文件目录不存在则直接告诉没有目录,而且不执行后面的命令;

实例2:如果文件目录不存在则执行后面的命令,如果在执行一次该命令就会报错,因为该文件已经存在所以后面的命令不执行;

while  until循环

语句格式:

while [判断式];do

程序内容

done  循环结束

实例:求100以内整数之和(经典案例拿来引用)

#!/bin/bash
declare -i sum=0
declare -i i=1
while [ $i -le 100 ]; do
        let sum+=$i
        let i++
done
echo "$sum"

结果:

until循环

语法格式:

与while相反

until condition;do

循环体

循环控制变量的修正表达式

done

进入条件:当condition失败时

退出条件:当condition成功时

实例:求100以内正整数之和

#!/bin/bashdeclare -i sum=0declare -i i=1until [ $i -gt 100 ]; do        let sum+=$i        let i++doneecho "$sum"

结果:

循环控制:

contion:提前结束本轮循环,而直接进入下一轮

break:提前终止循环

死循环:

Whine true;do

循环体

if condition;thenfidone#!/bin/bashusername=hzmwhile true;do        if who | grep "$username" &> /dev/null;then        echo "$username is logged"        break        fi        sleep 3done

结果:当hzm用户登录的时候脚本检测到该用户,并且执行break退出;

while特殊用法 :

while read VARIABLE;do

循环体

done < /PATH/FROM/SOME_FILE

case 循环

case $变量 in

Parttern1)

分支

;;

实例:

#!/bin/bash
read -p "please give number:" num
case $num in
"one")
        echo "this is one"
        ;;
"two")
        echo "this is two"
        ;;
"tree")
        echo "this is three"
        ;;
*)
        echo "Usage $0 {one|two|three}"
        ;;
esac

结果:

函数库

语法:

function:把一段具有独立功能代码封装在一起,并给与命名:后续用到时,可直接通过给定函数名来调用整体代码;

用法:

name () {

函数体

}

调用方法:

name[参数1,参数2]

实例:调用函数来ping一个B类地址

#!/bin/bash

#

PING() {

if ping -c 1 -w 1 $1 &> /dev/null; then

return 0

else

return 1

fi

}

HZM="210.14"

(

for S in {1..5}; do

for I in {1..5}; do

if PING $HZM.$S.$I; then

echo "$HZM.$S.$I is up."  >> /root/456.txt

else

echo "$HZM.$S.$I is down." >> /root/789.txt

fi

done

done

)&

wait

结果:显示在线的网址输出到456.txt中,不在线的输出到789.txt中;

函数模块化编程:

4、写一个脚本:如果某路径不存在,则将其创建为目录;否则显示其存在,并显示内容类型;(不要怀疑,就是这么简单)

方法:

#!/bin/bash
FILEtest=/tmp/hzm
if [ -e $FILEtest ]; then
        echo "$FILEtest exist"
        file $FILEtest
else
        mkdir -p $FILEtest
fi

结果:

[[email protected] ~]# bash -x test.sh

+ FILEtest=/tmp/hzm

+ ‘[‘ -e /tmp/hzm ‘]‘

+ echo ‘/tmp/hzm exist‘

/tmp/hzm exist

+ file /tmp/hzm

/tmp/hzm: directory

5、写一个脚本,完成如下功能;判断给定的两个数值,孰大孰小;给定数值的方法:脚本参数,命令交互;(使用read,依然如此简单)

方法:

#!/bin/bash
read -p "Please enter two values: " -t 10 values1 values2
if [ -z "$values1" ]; then
        echo "Please enter two values"
        exit 1
fi
if [ -z "$values2" ]; then
        echo "Plz give tow integers."
        exit 1
fi
if [ $values1 -ge $values2 ]; then
        echo "Max: $values1, Min: $values2."
else
        echo "Max: $values2, Min: $values1."
fi

结果:

[[email protected] ~]# sh number.sh

Please enter two values: 4 5

Max: 5, Min: 4.

[[email protected] ~]#

6、求100以内所有奇数之和(至少用3种方法。是的这是我们的作业^_^)

第一种:

#!/bin/bash

declare -i sum=0

for i in $(seq 1 2 100); do

sum=$[$sum+$i]

done

echo "$sum"

结果:

[[email protected] ~]# sh 2.sh

2500

[[email protected] ~]#

第二种:

#!/bin/bash

declare -i sum=0

declare -i i=1

while [ $i -le 100 ];do

if [ $[$i%2] -ne 0 ];then

let sum+=$i

fi

let i++

done

echo $sum

结果:

[[email protected] ~]# sh 2.sh

2500

[[email protected] ~]#

第三种:

方法:

#!/bin/bash

declare -i sum=0

for i in {1..100}; do

if [ $[$i%2] -ne 0 ]; then

sum=$[$sum+$i]

fi

done

echo "Even sum: $sum"

结果:

[[email protected] ~]# sh 1.sh

Even sum: 2500

[[email protected] ~]#

7、写一个脚本实现如下功能:

(1) 传递两个文本文件路径给脚本;

(2) 显示两个文件中空白行数较多的文件及其空白行的个数;

(3) 显示两个文件中总行数较多的文件及其总行数;

方法:

#!/bin/bash

if [ $# -lt 2 ];then

echo "two"

exit 1

fi

if [ $(grep "^$" $1 | wc -l) -gt $(grep "^$" $2 | wc -l) ];then

echo "more blank line file is $1" && echo "there are $(grep "^$" $1 | wc -l) blank lines"

else

echo "more blank line file is $2" && echo "there are $(grep "^$" $2 | wc -l) blank lines"

fi

if [ $(wc -l $1 | cut -d" " -f1) -gt $(wc -l $2 | cut -d" " -f1) ];then

echo "more line is $1" && echo "File number: $(wc -l $1)"

else

echo "more line is $2" && echo "File number: $(wc -l $2)"

fi

结果:

[[email protected]ost ~]# sh 3.sh /etc/fstab /etc/init.d/functions

more blank line file is /etc/init.d/functions

there are 76 blank lines

more line is /etc/init.d/functions

File number: 834 /etc/init.d/functions

[[email protected] ~]#

8、写一个脚本

(1) 提示用户输入一个字符串;

(2) 判断:

如果输入的是quit,则退出脚本;

否则,则显示其输入的字符串内容;

方法:

#!/bin/bash

read -p "please give Parameter:" -t 10 par

if [ -z $par ]; then

echo"please give Parameter:"

exit 1

fi

if [ $par == ‘quit‘ ]; then

exit 1

else

echo $par

fi

结果:输入‘quit’字符直接退出:

[[email protected] ~]# sh 4.sh

please give Parameter:quit

[[email protected] ~]#

输入其他字符:

[[email protected] ~]# sh 4.sh

please give Parameter:kkk

kkk

[[email protected] ~]#

9、写一个脚本,打印2^n表;n等于一个用户输入的值;(不好意思,我调皮了)

方法:

#!/bin/bash

read -p "please input number:" -t 10 num

if [ -z $num ]; then

exit 1

fi

count=2

for i in `seq 0 $num`;do

if [ $i -eq 0 ];then

echo "1"

elif  [ $i -eq 1 ];then

echo "2"

else

count+=x2

echo "$count=$[2**$i]"

fi

done

结果:

10、写一个脚本,写这么几个函数:函数1、实现给定的两个数值的之和;函数2、取给定两个数值的最大公约数;函数3、取给定两个数值的最小公倍数;关于函数的选定、两个数值都将通过脚本参数进行输入。

#!/bin/bash

if [ $# -lt 2 ];then

echo "two"

exit 1

sumnu() {

sum=$[$1+$2]

echo "the sum is $sum"

}

取两个值得最大公约数:

方法1:函数库内部调用本身(网上高手写的,思路很好拿来学习了^_^)

#!/bin/bash

#!/bin/sh

read -p "Input two positive integers: " a b

# Greatest Common Divisor

gcd()

{

if [ $2 -eq 0 ]; then

echo $1

else

gcd $2 `expr $1 % $2`

fi

}

gcd $a $b

方法2:

求最大公约数与最小公倍数的方法:

#!/bin/bash

if [ $# -ne 2 ];then

echo "USAGE:$0 integer1 integer2"

exit

fi

GCD()

{

a=$1

b=$2

if [ $a -lt $b ];then

max=$b

min=$a

else

max=$a

min=$b

fi

if [ $[$max%$min] -ne 0 ];then

GCD $min $[$max%$min]

fi

gcd=$min

}

LCM()

{

GCD $1 $2

b=$[$1*$2]]

lcm=$[$b/$gcd]

}

GCD $1 $2

LCM $1 $2

echo "gcd is $gcd, lcm is $lcm"

sed

命令解释:

是一种非交互式流编辑器,通过多种转换修改流经它的文本。默认情况下sed不会改变原文件本身,而只是对流经sed命令得文本修改,并将修改后的结果打印到屏幕。

Sed处理文本是以行为单位,每处理一行就立即打印出来,然后处理下一行,直到文本结束。

语法:

sed [options] file

选项:

d:删除 ---使用数字表示有多少行, 比如”1,5” “1 ~ 2”

实例:删除第3行。

实例2:删除1到3行的内容。

实例3:删除2到最后一行的内容。

实例4:删除最后一行的内容。

实例5:删除包含nine字符的行。

实例6:sed也支持正则表达式:比如”^$” 删除空行。

s:替换

参数:

-U:将\U后面的字符全部转换为大写

-u:吧\u后面第一个字符变成大写

-E:代表终止

实例1:将文本中is替换成to;

实例2:将文本中第二个单词is替换成to;

实例3:将文本中is全局替换成to;

实例4:替换第3行的This,替换为your;

替换is大写或者小写的字符,转换为your;

利用正则表达式替换[ ]内的字符为your;

另外一种做法,将[]内的内容替换成大写,利用-U来实现,反之-L转换为小写;

那如果只是转换一个字符呢,就利用-u来实现;

分组:(group)替换,于正则的用法一致;

a:在指定行下一行追加;

I:在指定行上一行追加;

c:命令是匹配条件的内容替换;

y:匹配内容替换为另外内容;

实例:在网卡目录下面最后一行增加dns1;

实例2:将文中i替换成t,s替换成o

i:文本修改;

实例:使用i命令在第2行前插入wo字符;

实例2:使用a命令在第二行后面插入wo字符;

实例3:在匹配的字符前面插入字符;

实例4:复杂一点的方法:将[]内的内容替换成yyYYe;

实例5:将/etc/sysconfig/network-scripts/ifcfg-eth0目录下的onboot改成off;

读入文本:

r:在匹配文中下一行添加另外的文件内容;

打印:-n是只显示参数的内容;

x:保持空间与模式空间互换:

h:把模式空间的内容拷贝到保持空间去:

H:把模式空间的内容追加到保持空间去:

g:把保持空间的内容写入到模式空间;

G:把保持空间的内容追加到模式空间;

awk

命令解释:

相比较sed的逐行处理文本,awk更倾向于将一行分割为字段处理;

工作机制是把指定的文本切成字段来做处理;

变量:1.内置变量;2自定义变量;

RS:输入行分隔符;

OFS:输出时的字段分隔符;

ORS:输出时的行分隔符;

语法格式:

awk [options] ‘program‘ file file

awk [options]‘{pattern + action}‘ {filenames}

常用命令:

print:简单输出命令

1.各项目之间使用逗号分隔,而输出时则使用输出分隔符分割;

2.输出的各item可以使用字符串或数值,当前记录字段,变量或awk得表达式;数值会被隐式转换为字符串后输出;

3.print后面item如果省略,相当于print $0:输出空白;

print  item1  item2(awk读取默认是空白作为分隔符,也可以指定分隔符)

例如: this  is   a  test----->$0    被分割为4个字符:

$1  $2  $3  $4

FS:输入时得字段分隔符;

RS:输入行分隔符;

OFS:输出时的字段分隔符;

ORS: 输出时的行分隔符;

NF:分隔字段数;

NR:行数;所有文件一并统计;

FNR:行数,个文件分别统计;

实例1:打印指定分隔符,能显示awk特性;

实例2:-F(指定分隔符)打印指定位置分隔符;

实例3:利用NF参数打印显示有几个域;

实例4:$NF打印最后一个域的字符;如果是倒数第2个域就-1;

实例5:NR:行数,对文件中的行做统计;

实例6:FNR:对两个文件的内容分别计算行数;

内置变量:

OFS:输出分隔符

实例5:利用输出分隔符来给每一个空格加上:

-v:给变量赋值;

FS=:输入分隔符;

OFS=# 输出分隔符;

-v:赋值

赋值给test=hi,同时在文本中加入变量;

printf format item1,item2....

format格式的指示符都%开头u,后跟一个字符:

%c:显示字符的ASCII码;

%d,%i:十进制整数;

%e,%E:科学记数法显示值;

%f:显示浮点数;

%g:%G:以科学计数法格式或浮点数格式显示数值;

$s:显示字符串;

%u:显示无符号整数;

%%:显示%自身;

修饰符:

#:显示宽度

-:左对齐

+:显示数值的符号;

.#:取至精度

实例1:

实例2:上个实例中添加上7,就是给特定字符宽度;

算术运算:+,-,*,/,%,-x,+x

赋值操作:=,+=,-=,如果自身是等于号/=/

awk的if条件表达式

selector?if-ture-expression:if--false-expression

实例:根据if条件表达式来做一个判断实例:

模式:

1.正则表达式:/正则表达式/;

2.表达式:0或1,货非空的字符串满足条件;

3.BEGIN:BEGIN{语句}....END{语句};仅在awk命令program运行之前运行一次,或者之后end之后执行一次;

4.组合模式:(&&),或(||),非(|);

实例1:正则表达式:

实例2:显示匹配到正则表达式的行;

实例3:匹配数字大于等于77的数字:

实例4:利用正则做模式匹配,把用户名与bash类型匹配的显示出来;

实例5:表达行范围,NR指定行的范围;

实例6:在文本首尾,BEGIN开始显示一行内容,END末尾显示一行内容;

控制语句:

if-else:if(condition){then body}else{else body}

while: while (condition) {while body}

do-while循环:

for循环:

数组:

实例1:显示字段数大于2的行;

实例2:显示第三段数字大于66的整行内容,否则就显示行号;

实例3:利用awk语句来计算100以内正整数之和;

实例4:遍历每一行的字符,如果大于等于3就显示出来;

时间: 2024-10-10 03:42:19

20150913-0915 shell,sed,awk的相关文章

无意中测试了grep,sed,awk的性能差异

最近从数据库中导出了230万条文本文件格式的数据记录.开了台freebsd虚拟机.ram 256Mb,cpu 1 core.其实就是测试在相同的硬件环境下,grep,sed,awk(nawk)三个工具的搜索文件的效率. 搜索结果: [[email protected]/var]# time grep 18921373250 vo.txt   //grep第一次搜索 /20101220/10000_18921373250_8_11623_20101220101118.pcm /20110513/1

grep,sed,awk

grep, sed 与 awk 相当有用 ! gerp 查找, sed 编辑, awk 根据内容分析并处理. awk(关键字:分析&处理) 一行一行的分析处理 awk '条件类型1{动作1}条件类型2{动作2}' filename, awk 也可以读取来自前一个指令的 standard input相对于sed常常用于一整行处理, awk则比较倾向于一行当中分成数个"字段"(区域)来处理, 默认的分隔符是空格键或tab键例如:last -n 5 | awk '{print $1

grep,sed,awk工具的使用

grep过滤特定的行 1.把包含'halt'的行以及这行下面的两行都打印出来. [[email protected] ~]# cp /etc/passwd /tmp/ [[email protected] ~]# cd /tmp/ [[email protected] tmp]# grep -A2 'halt' passwd halt:x:7:0:halt:/sbin:/sbin/halt mail:x:8:12:mail:/var/spool/mail:/sbin/nologin uucp:x

grep,sed,cut,awk,join个性特点

grep 从数据文件中查询/提取出含有特定关键字的行. sed 主要用于对数据文件中特定字符串的替换处理. cut 按照指定的分隔符(-d)剪下选定的列(-f num)或者字符(-c)的内容. awk 常用于只显示特定字段,或重新安排行内字段顺序. join 用来结合记录中具有共同键值的字段的文件. ---------------------------------------------------------------我是分割线-------------------------------

Linux_note 命令grep,sed,awk

1.grep 过滤出指定的行 grep  [-cinvABC]  'word'  filename --color 把匹配到的关键词用红色标识 如:# grep --color 'root' /etc/passwd -c :打印符合要求的行数 -i :忽略大小写 -n :在输出符合要求的行的同时连同行号一起输出 -v :打印不符合要求的行# cg -v 'root' 1.txt -A :后跟一个数字(有无空格都可以),例如 朅2则表示打印符合要求的行以及下面两行 # cg -A 2 -n 'ro

grep,sed,awk用法整理

grep -c 打印出符合要求的行数 -i 忽略大小写              ignore -n 连同符号一起输出          num -v 打印出不符合要求的行 -A2 本行及下面两行 -B2 本行及上面两行 -C2 本行及上下两行 grep ^root passwd    #过滤以root开头的行 grep root$ passwd    #过滤以root结尾的行 grep -i ^root passwd    #不区分大小写,过滤以root结尾的行 grep -E "^root|

Linux文本处理三剑客(grep,sed,awk)

grep sed awk 原文地址:http://blog.51cto.com/10461810/2095182

linux三剑客grep,sed,awk

grep 官方帮助文档 Usage: grep [OPTION]... PATTERN [FILE]... Search for PATTERN in each FILE or standard input. PATTERN is, by default, a basic regular expression (BRE). Example: grep -i 'hello world' menu.h main.c Regexp selection and interpretation: -E, -

mongoDB id 导出,dump,sed,count,mysql import等用法示例

#count collectiondb.news.count({"lpublishtime":{"$gte":1358697600000}}); #mongo导出mongoexport -h 192.168.1.175 --port 33000 -d booaa_so -c weibo -f '_id' -q "{\"lweibotime\":{\"\$gte\":1349020800000,\"\$lt\