读《Linux Shell脚本攻略》第4章笔记

    1. 正则表达式
    正则表达式的基本组成部分:
    ^       行起始标记
    $      行尾标记
    .       匹配任意一个字符
    []      匹配包含在[字符]之中的任意一个字符
    [^]     匹配除[^字符]之外的任意一个字符
    [-]     匹配[]中指定范围内的任意一个字符
    ?      匹配之前的项1次或0次
    +      匹配之前的项1次或多次
    *       匹配之前的项0次或多次
    ()      创建一个用于匹配的子串,例如:ma(tri)?匹配max或maxtrix
    {n}    匹配之前的项n次
    {n,}   之前的项至少需要匹配n次
    {n,m} 指定之前的项所必需匹配的最小次数和最大次数
    |        匹配|两边的任意一项
    \        转义符可以将上面介绍的特殊字符进行转义

    POSIX字符类是一个形如[:...:]的特殊元序列(meta sequence),它可以用于匹配特定的字符范围。
    POSIX字符表如下:
    [:alnum:] 字符与数字字符
    [:alpha:] 字母字符(包括大写字母与小写字母)
    [:blank:] 空格与制表符
    [:digit:] 数字字符
    [:lower:] 小写字母
    [:upper:] 大写字母
    [:punct:] 标点符号
    [:space:] 包括换行符、回车等在内的所有空白字符

    元字符是一种Perl风格的正则表达式,只有一部分文本处理工具支持它,并不是所有的工具支持它
    \b 单词边界
    \B 非单词边界
    \d 单个数字字符
    \D 单个非数字字符
    \w 单个单词字符(字母、数字与_)
    \W 单个非单词字符
    \n 换行符
    \s 单个空白字符
    \S 单个非空白字符
    \r 回车

    2. grep
    grep match_pattern filename或者grep “match_pattern” filename
    this is the line containing match_pattern #命令会返回包含给定match_pattern的文本行

    [root@server1 test]# echo -e “this is a word\nnext line” | grep word –color=auto
    this is a word

    grep命令通常将match_pattern视为通配符。如果要使用正则表达式,需要添加-E(extended)使用扩展正则表达式,也可以使用默认允许正则表达式的grep命令—egrep
    [root@server1 test]# echo -e “www.linuxeye.com 43243\n4444″ | grep -E “[a-z]+”
    www.linuxeye.com 43243
    [root@server1 test]# echo -e “www.linuxeye.com 43243\n4444″ | egrep “[a-z]+”
    www.linuxeye.com 43243

    #选项-o只输出文本中匹配到的文本部分
    [root@server1 test]# echo -e “www.linuxeye.com 43243\n4444″ | egrep -o “[a-z]+”
    www
    linuxeye
    com

    #选项-v(invert)将匹配结果进行反转
    [root@server1 test]# echo -e “www.linuxeye.com 43243\n4444″ | egrep -v “[a-z]+”
    4444

    #-c统计匹配行的数量,并不是匹配的次数
    [root@server1 test]# echo -e “www.linuxeye.com 43243\n4444\n3333″ | egrep -vc “[a-z]+”
    2

    #-n打印出包含匹配字符串的行号
    [root@server1 test]# echo -e “www.linuxeye.com 43243\n4444\n3333″ | egrep -vn “[a-z]+”
    2:4444
    3:3333

    #-b打印样式匹配所位于的字符或字节偏移,一行中字符串的字符偏移是从该行的第一个字符开始计算,起始值是0
    [root@server1 test]# echo -e “www.linuxeye.com 43243\n4444\n3333″ | egrep -vb “[a-z]+”
    23:4444
    28:3333

    #-l搜索多个文件并找出匹配文本位于哪一个文件中 -l相反选项-L,它会返回一个不匹配的文件列表
    [root@server1 test]# grep -l line2 *
    version1.txt
    version2.txt
    version.patch

    [root@server1 test]# grep -L line2 *
    filestat.sh
    other
    out.html
    remove_duplicates.sh
    test
    test_copy1
    test_copy2

    #-R递归搜索文件
    [root@server1 test]# grep -Rn “text” .

    #-i忽略样式中的大小写
    [root@server1 test]# echo www.LINUXEYE.COM | grep -i linuxeye
    www.LINUXEYE.COM

    #-e匹配多个样式中的一个
    [root@server1 test]# echo www.LINUXEYE.COM | grep -ie linx -e com
    www.LINUXEYE.COM

    #-f与-e选项以后,-f在样式文件中逐行写下匹配的样式
    [root@server1 test]# cat pat_file
    hello
    cool
    [root@server1 test]# echo “hello this is cool” | grep -f pat_file
    hello this is cool

    #在grep搜索中包含或排除文件
    只在目录中递归搜索所有的.c和.cpp文件
    [root@server1 test]# grep “main()” /usr -r –include *.{c,cpp}
    /usr/src/kernels/2.6.18-194.el5PAE-i686/scripts/kconfig/gconf.c: gtk_main();

    在搜索中排除所有的README文件
    [root@server1 test]# grep “main()” . -r –exclude “README”
    如果需要排除目录,可以使用–exclude-dir选项
    如果需要从文件中读取所需排除的文件列表,使用–exclude-from FILE

    使用0值字节后缀的grep与xargs
    [root@server1 test]# echo test > file1
    [root@server1 test]# echo cool > file2
    [root@server1 test]# echo test > file3
    [root@server1 test]# grep “test” file* -lZ | xargs -0 rm

    grep的静默输出
    -q(quiet mode)
    [root@server1 test]# cat file2
    cool
    [root@server1 test]# grep -q ‘co’ file2 ;echo $?
    0
    [root@server1 test]# grep -q ‘cookk’ file2 ;echo $?
    1

    打印出匹配文本的之前行或之后行
    [root@server1 test]# seq 10 | grep 5 -A 3
    5
    6
    7
    8
    [root@server1 test]# seq 10 | grep 5 -B 3
    2
    3
    4
    5
    [root@server1 test]# seq 10 | grep 5 -C 2
    3
    4
    5
    6
    7

    3. cut
    [root@server1 test]# cat data.txt
    No Name Mark Percent
    1 Sarath 45 90
    2 Alex 49 98
    3 Anu 45 90
    [root@server1 test]# cut -f 1,4 data.txt
    No Percent
    1 90
    2 98
    3 90

    #-complement选项对提前的字段进行补集运算
    [root@server1 test]# cut -f3 –complement data.txt
    No Name Percent
    1 Sarath 90
    2 Alex 98
    3 Anu 90

    要指定字段的定界符,使用-d选项
    [root@server1 test]# cat data1.txt
    No;Name;Mark;Percent
    1;Sarath;45;90
    2;Alex;49;98
    3;Anu;45;90
    [root@server1 test]# cut -f2,4 -d”;” data1.txt
    Name;Percent
    Sarath;90
    Alex;98
    Anu;90

    -b表示字节;-c表示字符;-f表示定义字段
    [root@server1 test]# cut -c-3 data1.txt
    No;
    1;S
    2;A
    3;A
    [root@server1 test]# cut -c2-4 data1.txt
    o;N
    ;Sa
    ;Al
    ;An

    4. 统计特定文件中的词频
    [root@server1 test]# cat word_freq.sh
    #!/bin/bash
    if [ $# -ne 1 ];
    then
    echo “Usage: $0 filename”;
    exit -1
    fi

    filename=$1
    egrep -o “\b[[:alpha:]]+\b” $filename | awk ‘{ count[$0]++ }END{ printf(“%-14s%s\n”,”Word”,”Count”);
    for(ind in count)
    { printf(“%-14s%d\n”,ind,count[ind]);}
    }’

    egrep -o “\b[[:alpha:]]+\b” $filename用来只输出单词。用-o选项打印由换行符分隔的匹配字符序列。
    \b是单词边界标记符。[:alpha:]是表示字母的字符类。

    5. sed
    [root@server1 test]# echo linuxeye.com linuxeyelinuxeyelinuxeye | sed ‘s/linuxeye/LINUXEYE/’
    LINUXEYE.com linuxeyelinuxeyelinuxeye
    [root@server1 test]# echo linuxeye.com linuxeyelinuxeyelinuxeye | sed ‘s/linuxeye/LINUXEYE/g’
    LINUXEYE.com LINUXEYELINUXEYELINUXEYE
    [root@server1 test]# echo linuxeye.com linuxeyelinuxeyelinuxeye | sed ‘s/linuxeye/LINUXEYE/2g’
    linuxeye.com LINUXEYELINUXEYELINUXEYE
    [root@server1 test]# echo linuxeye.com linuxeyelinuxeyelinuxeye | sed ‘s/linuxeye/LINUXEYE/4g’
    linuxeye.com linuxeyelinuxeyeLINUXEYE
    [root@server1 test]# echo linuxeye.com linuxeyelinuxeyelinuxeye | sed ‘s/linuxeye/LINUXEYE/2′
    linuxeye.com LINUXEYElinuxeyelinuxeye
    [root@server1 test]# echo linuxeye.com linuxeyelinuxeyelinuxeye | sed ‘s/linuxeye/LINUXEYE/4′
    linuxeye.com linuxeyelinuxeyeLINUXEYE
    不带参数g会将每一行中第一处符合样式的内容替换掉;带参数g则替换所有内容;数字表示从N处匹配开始替换
    参考://linuxeye.com/linux/104.html

    6. awk
    //linuxeye.com/linux/105.html
    # echo -e “line1 f2 f3\nline2 f4 f5\nline3 f6 f7″ | awk ‘{ print “line
    no: ” NR “,No of fields:” NF “,$0=”$0 ” ,$1=”$1 ” ,$2=”$2}’
    line no: 1,No of fields:3,$0=line1 f2 f3 ,$1=line1 ,$2=f2
    line no: 2,No of fields:3,$0=line2 f4 f5 ,$1=line2 ,$2=f4
    line no: 3,No of fields:3,$0=line3 f6 f7 ,$1=line3 ,$2=f6

    # seq 5 | awk ‘BEGIN{ sum=0; print “Summation:” }{ print $1″+”;sum+=$1 } END { print “==”; print sum }’
    Summation:
    1+
    2+
    3+
    4+
    5+
    ==
    15

    # VAR=1000
    # echo | awk -v VARIABLE=$VAR ‘{ print VARIABLE }’

    # var1=1; var2=2
    # echo | awk ‘{print v1,v2}’ v1=$var1 v2=$var2
    1 2

    #getline读取行
    # seq 5 | awk ‘BEGIN { getline;getline;print “test:”$0}{print $0}’
    test:2
    3
    4
    5

    #用样式对awk出来的行进行过滤
    awk ‘NR < 5′ #行号小于5的行
    awk ‘NR==2,NR==4′ #行号在2到4之间的行
    awk ‘/linuxeye/’ #包含样式linuxeye的行
    awk ‘!/linuxeye/’ #不包含样式linuxeye的行

    #设置字段定界符
    # awk -F: ‘{print $NF}’ /etc/passwd
    或者
    awk ‘BEGIN { FS=”:” } {print $NF}’ /etc/passwd

    #从awk中读取命令输出
    # echo | awk ‘{ “grep root /etc/passwd” | getline cmdout; print cmdout }’

    7. 压缩或解压缩JavaScript
    cat sample.js | tr -d ‘\n\t’ | tr -s ‘ ‘ | sed ‘s:/\*.*\*/::g’ | sed ‘s/ \?\([{}();,:]\) \?/\1/g’

    8. 按列合并文件
    [root@server1 test]# paste paste1 paste2
    1 test
    2 linuxeye
    3 com
    4 linux
    5 opensource
    [root@server1 test]# cat paste1
    1
    2
    3
    4
    5
    [root@server1 test]# cat paste2
    test
    linuxeye
    com
    linux
    opensource
    [root@server1 test]# paste paste1 paste2
    1 test
    2 linuxeye
    3 com
    4 linux
    5 opensource

    #默认的定界符是制表符,也可以用-d明确指定定界符,如下:
    [root@server1 test]# paste paste1 paste2 -d “:”
    1:test
    2:linuxeye
    3:com
    4:linux
    5:opensource

    9. 用脚本验证回文字符串
    sed命令能够记住之前匹配的子样式(sub pattern)。这被称为反向引用。我们可以借助这项功能解决回文问题。
    # cat match_palindrome.sh
    #!/bin/bash
    if [ $# -ne 2 ];
    then
    echo “Usage: $0 filename string_length”
    exit -1
    fi

    filename=$1
    basepattern=’/^\(.\)’
    count=$(( $2 / 2 ))
    for((i=1;i<$count;i++)) do basepattern=$basepattern’\(.\)’; done if [
    $(( $2 % 2 )) -ne 0 ]; then basepattern=$basepattern’.'; fi
    for((count;count>0;count–))
    do
    basepattern=$basepattern’\'”$count”;
    done
    basepattern=$basepattern’$/p’
    sed -n “$basepattern” $filename

    rev逆向打印出每一行内容
    echo this is linuxeye.COM | rev | tr ‘ ‘ ‘\n’ | tac | tr ‘\n’ ‘ ‘ | rev

    10. awk实现head、tail和tac
    head /etc/passwd awk实现:awk ‘NR<=10′ /etc/passwd
    tail /etc/passwd awk实现:awk ‘{ buffer[NR%10]=$0;} END {
    for(i=1;i<11;i++) { print buffer[i%10]}}’ /etc/passwd tac /etc/passwd
    awk实现:awk ‘{ buffer[NR] = $0; } END { for(i=NR;i>0;i–) { print
    buffer[i] } }’ /etc/passwd

    11. 文本切片与参数操作
    # var=”This is a line of text”
    # echo ${var/line/REPLACED}
    This is a REPLACED of text

    # string=http://www.linuxeye.com
    # echo ${string:7} #打印第7个字符之后的内容
    www.linuxeye.com
    # echo ${string:11:8} #从第11个字符开始,打印8个字符
    linuxeye

    其实字符的索引从0开始计数。我们也可以从后向前计数,将最后一个字符索引计为-1.但如果使用负数作为索引值得话,必须将负数放入括号内,例如(-1)就是最后一个字符的索引
    # echo ${string:(-12):8}
    linuxeye

    Mon Jan 7 15:15:52 CST 2013

    • 本文由 发表于 2013-01-07
    • 转载请务必保留本文链接:https://linuxeye.com/274.html
    Linux下内置命令和外部命令详解 Linux

    Linux下内置命令和外部命令详解

    Linux的命令分为内部命令和外部命令: 内部命令在系统启动时就调入内存,是常驻内存的,所以执行效率高。 外部命令是系统的软件功能,用户需要时才从硬盘中读入内存。 type可以用来判断一个命令是否为内...
    Linux shell用法和技巧 脚本

    Linux shell用法和技巧

    检查远程端口是否对bash开放: echo >/dev/tcp/8.8.8.8/53 && echo "open" 让进程转入后台: Ctrl + z 将进程转到前台: fg 产...
    浅谈Linux内存管理机制 Linux

    浅谈Linux内存管理机制

    经常遇到一些刚接触Linux的新手会问内存占用怎么那么多? 在Linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉是内存不够用了,其实不然。这是Linux内存管理的一个优秀特性,在...
    tmux - Linux终端管理软件 Linux

    tmux – Linux终端管理软件

    tmux是一个优秀的终端复用软件,类似GNU Screen,但来自于OpenBSD,采用BSD授权。使用它最直观的好处就是,通过一个终端登录远程主机并运行tmux后,在其中可以开启多个控制台而无需再“...
    匿名

    发表评论

    匿名网友