小练习

1.修改当前主机名为kali.org

  1. sed "s;$HOST;kali.org;" /etc/hostname

Sed—练习 - 图1
2.修改hosts文件,添加两条映射记录

  1. 192.168.60.30 www.qq.com
  2. 192.168.60.60 www.baidu.com

    1. sed '$a 192.168.60.30 www.qq.com \n192.168.60.60 www.baidu.com' /etc/hosts

    Sed—练习 - 图2

    综合练习

    练习1

    题目给出了一个data.txt文件内容如下,根据题目写出对应答案

    1. Steve Blenheim:238-923-7366:95 Latham Lane, Easton, PA 83755:11/12/56:20300
    2. Betty Boop:245-836-8357:635 Cutesy Lane, Hollywood, CA ,91464:6/23/23:14500
    3. Igor Chevsky:385-375-8395:3567 Populus Place, Caldwell, NJ 23875:6/18/68:23400
    4. Norma Corder:397-857-2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700
    5. Jennifer Cowan:548-834-2348:583 Laurel Ave., Kingsville, TX 83745:10/1/35:58900
    6. Jon DeLoach:408-253-3122:123 Park St., San Jose, CA 04086:7/25/53:85100
    7. Karen Evich:284-758-2857:23 Edgecliff Place, Lincoln, NB 92086:7/25/53:85100
    8. Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
    9. Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
    10. Fred Fardbarkle:674-843-1385:20 Parak Lane, DeLuth, MN 23850:4/12/23:780900
    11. Fred Fardbarkle:674-843-1385:20 Parak Lane, DeLuth, MN 23850:4/12/23:780900
    12. Lori Gortz:327-832-5728:3465 Mirlo Street, Peabody, MA 34756:10/2/65:35200
    13. Paco Gutierrez:835-365-1284:454 Easy Street, Decatur, IL 75732:2/28/53:123500
    14. Ephram Hardy:293-259-5395:235 CarltonLane, Joliet, IL 73858:8/12/20:56700
    15. James Ikeda:834-938-8376:23445 Aster Ave., Allentown, NJ 83745:12/1/38:45000
    16. Barbara Kertz:385-573-8326:832 Ponce Drive, Gary, IN 83756:12/1/46:268500
    17. Lesley Kirstin:408-456-1234:4 Harvard Square, Boston, MA 02133:4/22/62:52600
    18. William Kopf:846-836-2837:6937 Ware Road, Milton, PA 93756:9/21/46:43500
    19. Sir Lancelot:837-835-8257:474 Camelot Boulevard, Bath, WY 28356:5/13/69:24500
    20. Jesse Neal:408-233-8971:45 Rose Terrace, San Francisco, CA 92303:2/3/36:25000
    21. Zippy Pinhead:834-823-8319:2356 Bizarro Ave., Farmount, IL 84357:1/1/67:89500
    22. Arthur Putie:923-835-8745:23 Wimp Lane, Kensington, DL 38758:8/31/69:126000
    23. Popeye Sailor:156-454-3322:945 Bluto Street, Anywhere, USA 29358:3/19/35:22350
    24. Jose Santiago:385-898-8357:38 Fife Way, Abilene, TX 39673:1/5/58:95600
    25. Tommy Savage:408-724-0140:1222 Oxbow Court, Sunnyvale, CA 94087:5/19/66:34200
    26. Yukio Takeshida:387-827-1095:13 Uno Lane, Ashville, NC 23556:7/1/29:57000
    27. Vinh Tranh:438-910-7449:8235 Maple Street, Wilmington, VM 29085:9/23/63:68900

    题目1:显示包含San的行

    1. sed -n '/San/p' data.txt

    题目2:显示以J开头的人名所在的行

    1. sed -n '/^J/{=;p}' data.txt

    题目3:显示700结尾的行

    1. sed -n '/700$/p' data.txt

    题目4:显示不包834的行

    1. sed -n '/834/!p' data.txt

    题目5:显示电话号码的区号为834的行

    1. sed -n '/:834/{=;p}' data.txt

    题目6:显示这样的行:它包含一个大写字后跟四个小写字母,逗号,空格,和一个大写字母,并将逗号前面部分的字母用括号括起来

    1. sed -rn 's/([A-Z][a-z]{4})(,[[:space:]][A-Z])/[\1]\2/p' data.txt

    题目7:显示以K或k开头的行

    1. sed -rn '/^[kK]/p' data.txt

    题目8:显示工资为六位数的行

    1. sed -rn '/[^0][0-9]{6,}$/p' data.txt

    题目9:显示包括Lincoln或lincoln的行

    1. sed -rn '/Lincoln|lincoln/p' data.txt
    2. sed -rn '/[lL]incoln/p' data.txt

    题目10:把Jon的名字改成Jonathan

    1. sed -n 's#Jon#Jonathan#p' data.txt

    题目11:删除文件头3行内容

    1. sed -n '{1,3d;p}' data.txt

    题目12:显示5-10行

    1. sed -n '5,10{p;=}' data.txt

    题目13:把三个星*** * ***添加到有Fred的行

    1. sed -rn 's/^Fred/***&/p' data.txt

    题目14:删除空白行

    1. sed -n '/^$/d' data.txt

    练习2

    1、题目需求:

  3. 找到使用bash或zsh或sh登录shell的本地用户

  4. 列出这些用户shadow的密码记录
  5. 按每行”用户名 —-> 密码记录”进行输出

2、效果如下图所示:
Sed—练习 - 图3
3、思路:

  1. 获取所有符合要求的用户,将它们变成数组的形式,方便后续操作
  2. 遍历用户数组从/etc/shadow文件中查询出对应的密码
  3. 输出当前遍历到的用户和查询到的密码

4、脚本内容如下:

  1. #!/bin/bash
  2. # 过滤出以sh,zsh,bash结束的用户,并在后面添加一个=,方便分割行
  3. users=$(sed -rn '/[z]?sh$|bash$/p' /etc/passwd | xargs -I {} echo '{}=')
  4. # 保存原来的分隔符号,并设置新的分隔符号为=
  5. OLD_IFS="$IFS" && IFS='='
  6. # 将查询出来的用户变成数组形式
  7. users=($users)
  8. # 遍历用户数组
  9. for line in ${users[@]}
  10. do
  11. # 取名用户名(%%表示后向匹配到最长的删除)
  12. name=${line%%:*}
  13. # 去掉用户名中的换行
  14. name=`echo -n $name | tr -d "\n"`
  15. # 查询出用户名对应的密码
  16. prec=$(sed -n "/${name}/p" /etc/shadow)
  17. # 掐头:去掉开头用户名部分(#表示最顺序匹配去掉最短)
  18. pass=${prec#*:}
  19. # 去尾:去掉密码后面部分
  20. pass=${pass%%:*}
  21. # 输出用户名和密码
  22. echo -e "$name --> $pass"
  23. done
  24. # 恢复原来的分隔符
  25. IFS="$OLD_IFS"

5、运行结果
Sed—练习 - 图4

练习3

1、需求描述:

  • 处理一个类似于Windows的ini配置文件中的文本,提取出配置项目及对应的条目数量

2、例如:

  1. [init]
  2. dir=c:\windows\
  3. user=administrator
  4. arch=x64
  5. [running]
  6. task=12
  7. level=5
  8. [stop]
  9. clear_tmp_file=true
  10. background=false
  11. auto_remove=true

3、输出结果是:

  1. init ---> 3
  2. running ---> 2
  3. stop ---> 3

4、脚本内容如下

  1. #!/bin/bash
  2. # 默认配置文件
  3. default_file=/etc/mysql/my.cnf
  4. # 判断是否传入参数且参数对应的文件是否存在
  5. if [ ! -z $1 ] && [ -f $1 ];then
  6. FILE_NAME=$1
  7. else
  8. FILE_NAME=$default_file
  9. fi
  10. # 获取文件中的所有配置项
  11. function get_all_segment {
  12. sed -rn '/\[.*\]/{s#\[##;s#\]##p}' $FILE_NAME
  13. }
  14. # 获取配置项的数量
  15. function get_segment_count {
  16. # 取得配置项下的所有配置条目
  17. items=$(sed -rn "/$1/,/^\[/p" $FILE_NAME |egrep -v "^#|^$|^\[|^\!")
  18. # 将分隔符号设置成换行
  19. OLD_IFS=$IFS && IFS=$'\n'
  20. # 统计条目数量
  21. count=0
  22. for item in $items
  23. do
  24. let count++
  25. done
  26. # 恢复换行
  27. IFS=$OLD_IFS
  28. # 条目数
  29. echo "$count"
  30. }
  31. function main {
  32. # 遍历文件中所有的配置项目
  33. for segment in $(get_all_segment)
  34. do
  35. # 取出对应的条目
  36. count=$(get_segment_count $segment)
  37. # 输出配置项目及对应的条目数
  38. echo "$segment ---> $count"
  39. done
  40. }
  41. # 调用main函数
  42. main

5、运行结果
Sed—练习 - 图5