0
点赞
收藏
分享

微信扫一扫

SHELL中算术表达式的常见写法,bc,awk/gawk,sed

 

SHELL中算术表达式的常见写法


1)使用let :var=1  

                   let "var+=1"  

注意:  

a)let几乎支持所有的运算符,++、--、()

b)乘幂运算应使用“**”  

c)参数在表达式中直接访问,不必加$  

d)一般情况下算数表达式可以不加双引号,但是若表达式中有bash中的关键字则需加上  

e) let后的表达式只能进行整数运算  

f) let能够处理字符(置为0),表达式不需要空格






2)使用(( ))  

如:var=1  

((var+=1))  


注意:  

(())的使用方法与let完全相同  






3)使用$[]  

var=1  

var=$[$var+1]  

注意:  

a)$[]将中括号内的表达式作为数学运算先计算结果再输出  

b)对$[]中的变量进行访问时前面可不加$

c)$[]支持的运算符与let相同,但也只支持整数运算  

 





4)使用expr  

var=1  

var=`expr $var + 1`  

注意:  

a)expr后的表达式各符号间需用空格隔开  

b)expr支持的操作符有: |、&、<、<=、=、!=、>=、>、+、-、*、/、%  

c)expr支持的操作符中在使用时需用\进行转义的有:|、&、<、<=、>=、>、* 、/

e)expr同样只支持整数运算  

d)求串长,子串

格外注意:不建议用算术表达式作为关系运算!!


 






bc简介


bc命令可以很方便的进行浮点运算 ,它提供了一些语法结构,比如条件判断、循环等,可以说是很强大的 .

bc还可以用来进行数制转换 。






bc的用法之一:单独使用

子句用分号分隔;scale=2;3/4      # 保留小数点精度只对除法、取余、乘幂有效  

bc的用法之二:通过管道完成计算。

加减乘除,以加法为例: echo $a*$b|bc  

echo "3 * 4" | bc  

echo "scale=7; 355/113" | bc  

用$(  )来赋值,如:a=$(echo “3+5” |bc)




bc的用法之三:数制转化

ibase是输入数字的进制,obase是输出数字的进制。 (字母大写)echo "obase=16;ibase=10;10"|bc

 除了+-*/之外,bc 有三角函数,对数函数,指数函数,幂函数等

echo "m^n"|bc      m的n次方




s (x)  The sine of x, x is in radians.    正弦函数  

 c (x)  The cosine of x, x is in radians.  余弦函数  

 a (x)  The arctangent of x, arctangent returns radians. 反正切函数  

 l (x)  The natural logarithm of x.  log函数(以2为底)  

 e (x)  The exponential function of raising e to the value x.  e的指数函数  

 j (n,x)  The bessel function of integer order n of x.   贝塞尔函数





示例: 将多个表达式写在一个文件中一起计算

test.bc脚本如下

123*321

123/321

scale=4;123/321

运行脚本

[root@rhel ~]# bc test.bc

或者[root@rhel ~]# cat test.bc | bc

(第二种方式更适合写在脚本中)

39483

0

.3831  



awk是一个程式语言,对於资料的处理具有很强的功能,易于对於文档里的资料做修改、比对、抽取等的处理。

awk 能够依照使用者的定义格式来分解输入资料,也可依照使用 者定义的格式来印出资料。 awk 名称的由来是由它的原始设计者的姓氏之第一个字母而命名。

gawk 是GNU所做的 awk。

awk/gawk简介


gawk 的主要功能是针对档案的每一行搜寻指定的 patterns,并对符合的行执行被指定的 actions。 gawk 依此方式处理输入档案的每一行直到输入档案结束。

gawk 程式是由很多的 pattern 与 action 所组成,一个pattern後面就跟著一个action:  

pattern {action}

pattern {action}

如果 pattern 被省略,对於输入档里面的每一行,action 都会被执行。如果 action 被省略,内定的 action则会印出所有符合 pattern 的输入行。




有2个方法可以执行gawk程式。

gawk 程式很短,则 可以直接写在命令行:  

gawk 'program' input-file1 input-file2 ...  

其中 program 包括一些 pattern 和 action。  

如果 gawk 程式较长,将 patterns 与 actions 写在档名为 program-file 的档案里面,执行gawk 的格式如下所示:  

gawk -f program-file input-file1 input-file2 ...  

或  

gawk -f program-file1 -f program-file2 ... input-file1 input-file2 ...  




例:gawk '/foo/ {print $0}' BBS-list  

gawk 程式为 /foo/ {print $0}。/foo/ 为 pattern,意思为搜寻输入档里的每一行是否含有子字串 'foo',若有 则执行 action。action 为 print $0;


pattern处也可以是关系或逻辑表达式,如:

gawk '$1 == "Feb" {sum=$2+$3} END {print sum}' shipped


gawk的输入可以从标准输入或指定的档案里读取(没有文件名就从标准输入)。

输入的读取单位被称为记录(records),每个记录的内定值是一行(line),一个记录又被分为多个域(fields)。

内建变量 RS为记录分隔字串,内定值是"\n"。

内建变量 FNR 会储存目前的输入档案已经被读取的记录之个数。内建变量 NR 会储存目前为止所有的输入档案已经被读取的记录之个数。



域之间是以 whitespace 分开。在gawk 里,whitespace 的意思是一个或多个空白或 tabs。(分隔符FS)

在 gawk 程式里面,以'$1'表示第一个域,'$2'表示第二个域,依此类推。$0,表示整个记录。

例:检查第一个域是否包含指定字串

gawk '$1~/foo/ {print $0}' BBS-list




print 叙述用在简单、标准的输出格式。叙述的格式如下所示:

print item1, item2, ...输出时,各个 item 之间会以一个空白分开,最後会换行(newline)。

如果 'print'叙述之後没有跟著任何东西,它与'print $0'的效果一样。

要印出空白行可使用'print" "'。

印出一段固定的文字,可用双引号,例如'print "Hello there"'。

gawk '{print $1,$2}' shipped



内建变量 OFS(output field separator)的初始值为" ",即空格。

内建变量ORS( outputrecord separator)用来指明每行输出完后的分隔字串。ORS 的初始值为 "\n"。

例:印出每个记录的第一、第二两个域,以分号';'分开,每行输出之後会加入一个空白行。

gawk 'BEGIN {OFS=";"; ORS="\n\n"} {print $1, $2}' BBS-list



描述pattern的方法可以使用正则表达式/regular expression/

每当输入记录 (record)含有 regular expression 就视为符合。

expression

   一个单一的 expression。当一个值不为 0 或一个字串不是空的,则可视为符合。

pat1,pat2

  一对的 patterns 以逗号分开,指定记录的范围。

BEGIN

END

    这是特别的 pattern, gawk 在开始执行或要结束时会分别执行相对应於BEGIN或END的 action。

null

   这是一个空的pattern,对於每个输入记录皆视为符合pattern。

exp ~ /regexp/

   如果 exp 符合 regexp,则结果为真(true)。

exp !~ /regexp/

   如果 exp 不符合 regexp,则结果为真。


x<=y 如果 x 小於、等於 y,则结果为真。

x>y 如果 x 大於 y,则结果为真。

x>=y 如果 x 大於、等於 y,则结果为真。

x==y 如果 x 等於 y,则结果为真。

x!=y 如果 x 不等於 y,则结果为真。

x~y 如果 x 符合 regular expression y,则结果为真。

x!~y 如果 x 不符合 regular expression y,则结果为真。


如果x 与 y二者皆是数字则视为数字之间的比较,

否则它们会被转换成字串且以字串的形式做比较。



使用逻辑运算的Patterns


一个 pattern 是使用逻辑运算"或"('||'),"与"

('&&'),"非"('!')来组合其它的pattern。

例如:


gawk '/2400/ && /foo/' BBS-list

gawk '/2400/ || /foo/' BBS-list

gawk '! /foo/' BBS-list

awk '$1>1 && $1<3' score.txt  



sed 是一种流编辑器

sed一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。

sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。  

sed 简介


sed命令  

调用sed命令有两种形式:  

sed [options] 'command' file(s)  

sed [options] -f scriptfile file(s)  


在文本或流中替换和删除字符串是sed最基本的用途  

sed 's/Mr.smith/Mis.smith/g' filea #全部内容

sed 's/the//' filea  #删除每行第一个the

如果用双引号shell将解释其中的内容

如:sed -n "/$a/p" score.txt



sed -n '3,12p' filea

sed -n '2,$p' filea sed -n '2,4d' filea 删行

\(..\) 标识匹配的字符串,在s命令中可以有若干不同的标识,并用数字区分和指示

如命令: echo loveable |sed 's/\(love\)able/\1rs/'

则loveable被替换成lovers。

s/\(love\)ab\(le\)/\2rs/,则loveable被替换成lers

如果利用特殊的字符做标志则可以截取字符串:

echo "asdfkjasldjkf\"shiner\"df" | sed 's/\(.*\)"\(.*\)"\(.*\)/\2/'

这里双引号成为不同字符串的分割标志



如对路径字符串做截取

令pathstr='/first/second/third'

echo $pathstr|sed 's/\(.*\)\/\(.*\)\/\(.*\)/\1/g'

/first

echo $pathstr|sed 's/\(.*\)\/\(.*\)\/\(.*\)/\2/g'

second

echo $pathstr|sed 's/\(.*\)\/\(.*\)\/\(.*\)/\3/g'

third




echo 'first"second"third'|sed 's/\(.*\)"\(.*\)"\(.*\)/\1\3/g'

firstthird

如果只有一个标识,可以对字符串做析取:

echo 'first"second"third'|sed 's/\(.*\)st/\1/g'

fir"second"third

echo 'first"second"third'|sed 's/\(.*\)con/\1/g'

first"sed"third




典型的用法1:

   从不完全规格化文件中提取需要的变量keyword的值

sed -n 's/:/\n/gp' filename (以:分割按行分离)

   sed -n '/keyword/p' (关键字搜索,类grep)

  sed -n 's/keyword=//gp'  (关键字字段值提取)


文件往往不是完全规格化的,这时可以借助sed进行整理后再处理




如文件 /proc/cmdline内容为:

BOOT_IMAGE=/vmlinuz-3.10.0-1127.18.2.el7.x86_64 root=/dev/mapper/centos_mytest2-root ro crashkernel=auto rd.lvm.lv=centos_mytest2/root rd.lvm.lv=centos_mytest2/swap rhgb quiet LANG=zh_CN.UTF-8

若要获取其中 root=/dev/VolGroup00/LogVol00 rhgb quiet的有关内容

则sed -n 's/ /\n/gp' /proc/cmdline|sed -n '/root/p'|sed -n 's/root=//gp'

得到/dev/VolGroup00/LogVol00

(或echo $listring|sed -n 's/ /\n/gp')



典型的用法2:

    从文件中删除指定的行或字符

删掉文件file1中的空行:

sed '/^$/d' file1

'/正则表达式/'可以匹配需要的行

删除特定字符:

echo '23%'|sed -n 's/%//p'

echo '23%'|sed 's/\(.*\)%/\1/'

比较${a%\%*},a=23%



典型的用法3:从文件(或输出)中提取指定的行或字符

ifconfig ens33|sed -nr '2s/^.*inet(.*)netmask.*$/\1/gp'

比较:

ifconfig ens33|sed -nr '2s/^.*inet(.*)netmask(.*$)/\2/gp'


举报

相关推荐

0 条评论