注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

小楼一夜听风雨

计算机知识、分子模拟、Linux学习,与您共分享!

 
 
 

日志

 
 

Shell数值、字符串比较及Sed实例  

2010-06-17 20:46:39|  分类: Linux学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
 

Shell中字符串、数值的比较

二元比较操作符,比较变量或者比较数字.注意数字与字符串的区别.
 
整数比较
 
-eq        等于,如:if [ "$a" -eq "$b" ]
-ne        不等于,如:if [ "$a" -ne "$b" ]
-gt        大于,如:if [ "$a" -gt "$b" ]
-ge        大于等于,如:if [ "$a" -ge "$b" ]
-lt        小于,如:if [ "$a" -lt "$b" ]
-le        小于等于,如:if [ "$a" -le "$b" ]
<        小于(需要双括号),如:(("$a" < "$b"))
<=        小于等于(需要双括号),如:(("$a" <= "$b"))
>        大于(需要双括号),如:(("$a" > "$b"))
>=        大于等于(需要双括号),如:(("$a" >= "$b"))
 
字符串比较
=        等于,如:if [ "$a" = "$b" ]
==        等于,如:if [ "$a" == "$b" ],与=等价
        注意:==的功能在[[]]和[]中的行为是不同的,如下:
        1 [[ $a == z* ]]    # 如果$a以"z"开头(模式匹配)那么将为true
        2 [[ $a == "z*" ]]  # 如果$a等于z*(字符匹配),那么结果为true
        3  
        4 [ $a == z* ]      # File globbing 和word splitting将会发生
        5 [ "$a" == "z*" ]  # 如果$a等于z*(字符匹配),那么结果为true
        一点解释,关于File globbing是一种关于文件的速记法,比如"*.c"就是,再如~也是.
        但是file globbing并不是严格的正则表达式,虽然绝大多数情况下结构比较像.
!=        不等于,如:if [ "$a" != "$b" ]
        这个操作符将在[[]]结构中使用模式匹配.
<        小于,在ASCII字母顺序下.如:
        if [[ "$a" < "$b" ]]
        if [ "$a" \< "$b" ]
        注意:在[]结构中"<"需要被转义.
>        大于,在ASCII字母顺序下.如:
        if [[ "$a" > "$b" ]]
        if [ "$a" \> "$b" ]
        注意:在[]结构中">"需要被转义.
        具体参考Example 26-11来查看这个操作符应用的例子.
-z        字符串为"null".就是长度为0.
-n        字符串不为"null"
        注意:
        使用-n在[]结构中测试必须要用""把变量引起来.使用一个未被""的字符串来使用! -z
        或者就是未用""引用的字符串本身,放到[]结构中。虽然一般情况下可
        以工作,但这是不安全的.习惯于使用""来测试字符串是一种好习惯.

 

SHELL下的数字比较及计算举例

比较:
方法一: if [ ${A} -lt ${B} ]; then ...
这是最基本的比较方法,使用lt(小于),gt(大于),le(小于等于),ge(大于等于),优点:还没发现;缺点:只能比较整数,使用lt,gt等不直观
方法二: if ((${A} < ${B})) then ...
这是CShell风格比较,优点:不用使用lt,gt等难记的字符串;缺点:还是只能比较整数
方法三: if (echo ${A} ${B} | awk '!($1>$2){exit 1}') then ...
这是使用awk比较,优点:可以比较小数;缺点:表达式太复杂,难记
方法四: if (echo ${A} - ${B} | bc -q | grep -q "^-"); then ...
这是使用bc计算比较,优点:可以比较小数;缺点:表达式更复杂,难记

计算:
方法一:typeset C=$(expr ${A} + ${B});
SHELL中的基本工具,优点:方便检测变量是否为数字;缺点:只能计算整数,且只能计算加减法,不能计算乘除法
方法二:let "C=${A}+${B}"; 或 let "C=A+B"
内嵌命令计算,优点:能计算乘除法及位运算等;缺点:只能计算整数
方法三:typeset C=$((A+B))
CShell风格的计算,优点:能计算乘除法及位运算等,简介,编写方便;缺点:不能计算小数
方法四:typeset C=${echo ${A} ${B} | awk '{print $1+$2}')
使用awk计算,优点:能计算小数,可以实现多种计算方式,计算灵活;缺点:表达式太复杂
方法五:typeset C=${echo ${A} + ${B} | bc -q)
使用awk计算,优点:能计算小数,计算方式比awk还多,计算灵活;缺点:表达式太复杂,小数点后面的位数必须使用scale=N来设置,否则可能会将结果截断为整数

 

 

sed/awk与unix命令等价代码


 


cat            |  sed ':'

cat -s         |  sed '/./,/^$/!d'

tac            |  sed '1!G;h;$!d'

grep           |  sed '/patt/!d'

grep -v        |  sed '/patt/d'

head           |  sed '10q'

head -1        |  sed 'q'

tail           |  sed -e ':a' -e '$q;N;11,$D;ba'

tail -1        |  sed '$!d'

tail -f        |  sed -u '/./!d'

cut -c 10      |  sed 's/\(.\)\{10\}.*/\1/'

cut -d: -f4    |  sed 's/\(\([^:]*\):\)\{4\}.*/\2/'

tr A-Z a-z     |  sed 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'

tr a-z A-Z     |  sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'

tr -s ' '      |  sed 's/ \+/ /g'

tr -d '\012'   |  sed 'H;$!d;g;s/\n//g'

wc -l          |  sed -n '$='

uniq           |  sed 'N;/^\(.*\)\n\1$/!P;D'

rev            |  sed '/\n/!G;s/\(.\)\(.*\n\)/&\2\1/;//D;s/.//'

basename       |  sed 's,.*/,,'

dirname        |  sed 's,[^/]*$,,'

xargs          |  sed -e ':a' -e '$!N;s/\n/ /;ta'

paste -sd:     |  sed -e ':a' -e '$!N;s/\n/:/;ta'

cat -n         |  sed '=' | sed '$!N;s/\n/ /'

grep -n        |  sed -n '/patt/{=;p;}' | sed '$!N;s/\n/:/'

cp orig new    |  sed 'w new' orig[/code:1:739eb4cef5]


 



-------------------------------------------------------------------------------

cat            |awk '{print}'

cat -s         |awk '{blank = NF == 0 ? ++blank : 0; if (blank <= 1) print;}'

tac            |awk '{t[NR] = $0;}END{for (i = NR; i >= 1; i--) print t[i];}'

grep patten    |awk '/patten/{print}'

grep -v patten |awk '! /patten/{print}'

head           |awk 'NR <= 10 {print}' 24.sh

head -1        |awk '{print; exit; }' 24.sh

tail           |awk '{t[n++ % 10] = $0}END{for (i = 0; i < 10; i++) print t[n++ % 10];}'

tail -1        |awk '{t = $0}END{print t}'

cut -c 10      |awk '{print substr($0, 10, 1)}'

cut -d: -f4    |awk -F: '{if (NF > 1) print $4; else print;}'

tr A-Z a-z     |awk '{print tolower($0);}' se.sh

tr a-z A-Z     |awk '{print toupper($0);}' se.sh

tr -s ' '      |awk '{print gensub(" +", " ", "g")}'

tr -d '\012'   |awk '{printf "%s", $0}'

wc -l          |awk 'END{printf "% 7d\n", NR-1}'

uniq           |awk '{if (NR == 1 || ln != $0) print; ln = $0;}'

rev            |awk '{l = ""; for (i = length($0); i > 0; i--) printf "%c", substr($0, i, 1); print "";}'

basename       |awk -F'/' '{print $NF}'

dirname        |awk -F'/' '{if (NF <= 1) printf "."; else {OFS="/"; $NF=""; printf "%s", substr($0, 1, length($0) - 1);}}'

xargs          |awk '{printf "%s ", $0}END{print}'

paste -sd:     |awk 'NR > 1{printf ":%s", $0}'

cat -n         |awk '{printf "% 6d  %s\n", NR, $0}'

grep -n        |awk '/ss/{print NR":"$0}'

cp orig new    |awk '{print > "new"}' orig


 

 sed是一个非交互性性文本编辑器, 它编辑文件或标准输入导出的文件拷贝。标准输入可能是来自键盘、文件重定向、字符串或变量,或者是一个管道文件。sed可以随意编辑小或大的文件,有许多 sed命令用来编辑、删除,并允许做这项工作时不在现场。sed一次性处理所有改变,因而变得很有效,对用户来说,最重要的是节省了时间。sed必须通过行号和正则表达式指定要改变的文本行

sed怎样读取数据:
    sed从文件的一个文本行或从标准输入的几种格式中读取数据,将之拷贝到一个编辑缓冲区,然后读命令行或脚本的第一条命令,并使用这些命令查找模式或定位行号编辑它,重复过程直到命令结束

sed命令的调用:
    在命令行键入命令;将sed命令插入脚本文件,然后调用sed;将sed命令插入脚本文件,并使sed脚本可执行
    sed [option] sed命令 输入文件            在命令行使用sed命令,实际命令要加单引号
    sed [option] -f sed脚本文件 输入文件     使用sed脚本文件
    sed脚本文件 [option] 输入文件            第一行具有sed命令解释器的sed脚本文件
    option如下:
      n 不打印; sed不写编辑行到标准输出,缺省为打印所有行(编辑和未编辑),p命令可以用来打印编辑行
      c 下一命令是编辑命令,使用多项编辑时加入此选项
      f 如果正在调用sed脚本文件,使用此选项,此选项通知sed一个脚本文件支持所用的sed命令,如
          sed -f myscript.sed input_file  这里myscript.sed即为支持sed命令的文件
    使用重定向文件即可保存sed的输出

使用sed在文本中定位文本的方式:
    x       x为一行号,比如1
    x,y     表示行号范围从x到y,如2,5表示从第2行到第5行
    /pattern/    查询包含模式的行,如/disk/或/[a-z]/
    /pattern/pattern/   查询包含两个模式的行,如/disk/disks/
    /pattern/,x  在给定行号上查询包含模式的行,如/disk/,3
    x,/pattern/  通过行号和模式查询匹配行,如 3,/disk/
    x,y!    查询不包含指定行号x和y的行

基本sed编辑命令:
    p      打印匹配行                      c\    用新文本替换定位文本
    =      显示文件行号                    s     使用替换模式替换相应模式
    a\     在定位行号后附加新文本信息        r     从另一个文本中读文本
    i\     在定位行号后插入新文本信息        w     写文本到一个文件
    d      删除定位行                      q     第一个模式匹配完成后退出或立即退出
    l      显示与八进制ASCII代码等价的控制字符        y  传送字符
    n      从另一个文本中读文本下一行,并附加在下一行   {}     在定位行执行的命令组
    g      将模式2粘贴到/pattern n/

基本sed编程举例:
    使用p(rint)显示行: sed -n '2p' temp.txt   只显示第2行,使用选项n
    打印范围:  sed -n '1,3p' temp.txt         打印第1行到第3行
    打印模式:  sed -n '/movie/'p temp.txt     打印含movie的行
    使用模式和行号查询:  sed -n '3,/movie/'p temp.txt   只在第3行查找movie并打印
    显示整个文件:  sed -n '1,$'p temp.txt      $为最后一行
    任意字符:  sed -n '/.*ing/'p temp.txt     注意是.*ing,而不是*ing
    打印行号:  sed -e '/music/=' temp.txt
    附加文本:(创建sed脚本文件)chmod u+x script.sed,运行时./script.sed temp.txt
        #!/bin/sed -f
        /name1/ a\             #a\表示此处换行添加文本
        HERE ADD NEW LINE.     #添加的文本内容
    插入文本: /name1/ a\ 改成 4 i\ 4表示行号,i插入
    修改文本: /name1/ a\ 改成 /name1/ c\ 将修改整行,c修改
    删除文本: sed '1d' temp.txt  或者 sed '1,4d' temp.txt
    替换文本: sed 's/source/OKSTR/' temp.txt     将source替换成OKSTR
             sed 's/\$//g' temp.txt             将文本中所有的$符号全部删除
             sed 's/source/OKSTR/w temp2.txt' temp.txt 将替换后的记录写入文件temp2.txt
    替换修改字符串: sed 's/source/"ADD BEFORE" &/p' temp.txt
             结果将在source字符串前面加上"ADD BEFORE",这里的&表示找到的source字符并保存
    sed结果写入到文件: sed '1,2 w temp2.txt' temp.txt
                     sed '/name/ w temp2.txt' temp.txt
    从文件中读文本: sed '/name/r temp2.txt' temp.txt
    在每列最后加文本: sed 's/[0-9]*/& Pass/g' temp.txt
    从shell向sed传值: echo $NAME | sed "s/go/$REP/g"   注意需要使用双引号

快速一行命令:
    's/\.$//g'         删除以句点结尾行
    '-e /abcd/d'       删除包含abcd的行
    's/[][][]*/[]/g'   删除一个以上空格,用一个空格代替
    's/^[][]*//g'      删除行首空格
    's/\.[][]*/[]/g'   删除句号后跟两个或更多的空格,用一个空格代替
    '/^$/d'            删除空行
    's/^.//g'          删除第一个字符,区别  's/\.//g'删除所有的句点
    's/COL/(...\)//g'  删除紧跟COL的后三个字母
    's/^\///g'         删除路径中第一个\

 

  评论这张
 
阅读(3304)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017