zoukankan      html  css  js  c++  java
  • shell_processing

    1、文本处理_2:grep,sed,awk
    2、regular_expression
    3、Test
     
    一、文本处理_2
    1、grep --Linux处理正则表达式的主要程序。正则表达式是一种符号表示法,用于识别文本模式
    常用选项:
    -w --匹配单词的边界
    -o --输出匹配的那部分,而不是整行
    -i --忽略大小写
    -R --递归,用于搜索目录下的文件
    -l --输出符合条件的文件名
    -n --显示匹配记录的行号
    -v --显示不符合条件的结果
    -c --输出匹配的记录的总数
    -A --输出下文(after)
    -B --输出上文(before)
    -C --输出上下文(context)
    -q --不输出结果,常用于条件测试
    -E --使用扩展的正则表达式;表达重复的数量时,在大括号前面不需要反斜杠,这样正则表达式就很简洁,易读
    # grep bin /etc/passwd --把/etc/passwd 中包含 bin 的行列出来
    # grep -w bin /etc/passwd --对搜索字符有边界限制
    # grep -o bin /etc/passwd --只列出匹配到的字符串
    # grep -oi nobody /etc/passwd --将匹配到的字符列出,不区分大小写
    # grep -Rl AUTOSWAP /etc/sysconfig/ --指定目录里面,哪个文件包含了字符串AUTOSWAP
    # grep -n bash /etc/passwd | awk -F: '{print $1}' --找出指定文件中 bash 所在的行的行号
    # grep -n bin /etc/passwd | wc -l --找出指定文件中有多少行包含了单词bin
    # grep -nv bash /etc/passwd --找出 /etc/passwd 中不包含bash 的行
    # grep -c root /etc/passwd --输出匹配行的总数
    # grep -A2 mail /etc/passwd --打印出指定文件中包含 mail 的行,同时打出其下面2行
    # grep -B2 mail /etc/passwd --同上,同时打出其上面2行
    # grep -C2 mail /etc/passwd --同上,同时打出其上下面各2行
    # grep -q root /etc/passwd --不输出结果,经常用于脚本中,用来做测试
    # echo $? --返回值为 0,匹配到字符;否则未匹配到指定字符
    # ls /bin | grep '^.{5}$' --输出 /bin 目录下只有五个字符的命令
    # ls /bin | grep -E '^.{5}$' -- 使用扩展的正则表达式
    # grep -Eo '/[^:]*nologin$' /etc/passwd --正则表达式与边界限制组合
    # echo -e "1 2" -- -e,使 echo 使用正则表达式
    --------------------------------------------------------------------------------------------------------------
    # cat lines | grep -v '^$' |grep -vE '^s+$' --删除含有空格与含有TAB的空白行
     
    2、sed --流编辑器,常常用于脚本中
    范围指定:不明确指定的话,默认是所有的行;可以是行号;或者正则表达式
    动作指定:
    d --删除
    s --替换
    n --关闭默认的输出
    p --打印
    e --连续符
    -i --将修改结果写入原文件,默认是将修改结果输出到标准输出
    i --在前面插入
    a --在后面插入
    -r --使用扩展的正则表达式,使用这个参数后正则表达式的表示方法会更加方便。相当于 grep 里的 -E
    2.1、删除
    # cat /etc/passwd | sed '3d' --删除第 3 行
    # cat /etc/passwd | sed '3,$d' --删除第 3 行至最后
    # cat /etc/passwd | sed '10,20d' --删除第 10 行至第 20 行
    # head /etc/passwd | cat -n |sed -e 1d -e 3d --删除第 1 行与第 3 行
    2.2、替换
    # echo hello | sed 's/l/L/' --把小写 l 替换成大写 L,只匹配第 1 个 l
    # echo hello | sed 's/l/L/g' --匹配所有的 l
    # grep root /etc/passwd | sed 's/root/ROOT/' --为指定范围,替换所有行第 1 个 root
    # grep root /etc/passwd | sed '1s/root/ROOT/' --只替换第 1 行第 1 个 root
    # echo "hello world" | sed 's/world//' --将字符串替换为空
    替换动作的范围:
    s/a/A/ --替换每行第一个a
    s/a/A/g --替换每行所有a
    s/a/A/3 --替换每行第3个a
    s/a/A/3g --替换每第3个至最后一个a
    替换命令的分割符:
    分隔符斜杠/ 可以换成任何其它的字符,需要注意的是,如果需要处理的数据中包含了分隔符,就必须对该字符进行转义,举例如下:
    # echo /etc/passwd | sed 's///_/g' --将字符串中的斜杠替换成下划线
    # echo /etc/passwd | sed 's#/#_#g' --作用同上,使用其他字符作为分隔符
    2.3、输出指定行
    # sed -n '1,5p' /etc/passwd -- -n关闭了默认的输出,然后只输出第1至第5行
    # sed -n '/root/p' /etc/passwd -- 输出包含指定关键字的行
    2.4、插入
    # cat /etc/passwd | sed '5i good morning' --在第 5 行前面插入一行
    # cat /etc/passwd | sed '3a good morning' --在第 3 行后面插入一行
    # cat /etc/passwd | sed '4i good morning' | sed '3a good morning' --通过管道可随意插入
    # cat /etc/passwd | sed -e '4i good morning' -e '3a good morning' --也可使用连续符
    2.5、正则
    # sed '/^.{5}x/d' /etc/passwd | cat -n --删除指定文件第 6 个字符为 x 的每行
    # sed -r '/^.{5}x/d' /etc/passwd --同上
    # echo 123456789ABCDEF | sed -r 's/^(.{2})...(.*)$/12/' --删除第 3 至第 5 的字符
    # echo 123456789ABCDEF | sed -r 's/^(.{2}).(.*)$/12/' --删除第 3 个字符
    # echo 123456789ABCDEF | sed -r 's/^(.{2}).{10}(.*)$/12/' --删除从3个字符开始的10个字符
    # echo abc | sed -r 's/[a-z]/u&/g' --小写转为大写
    # echo ABC | sed -r 's/[A-Z]/L&/g' --大写转为小写
    # echo ABC | sed -r 's/./l&/g' --同上
    # sed -r -e '/^$/d' -e '/^s+$/d' /path/file --删除空白行 以及 含有空格的空白行
    # sed -r '/^(s+)?$/d' /path/file --同上
    # sed -r '/xxxxxx/d' --删除包含指定关键字的行
     
    3、awk --文本分析工具
    -F --字段分割符,可以是一个字符,也可以是多个字符。默认的分割符为单个或连续的空格
    $NF --最后一个列,NF 是number of fields:有字段的总数
    $0 --整条记录
    # awk -F '[ :]' '{print $3,$4}' /etc/passwd --以 【空格符】 or 【:】 为分隔符
    # head /etc/passwd | awk -F: '{print $1,$2}' | column -t
    # echo 'hello world, good morning' | awk -F, '{print $1}'
    # head -n5 /etc/passwd | awk -F: '{print $NF}' --拿文件各行的最后一列,不管文件几行内容列数是否相同
    3.1、FS
    Field separator:字段分割符。字段分割符除了可以通过命令行选项 -F 来指定外,还可以在awk 里面指定
    BEGIN:后面的代码会在处理第一行数据之前先执行,可以在这里做一些前期的设定,比如设定分割符FS
    # head -n5 /etc/passwd | awk 'BEGIN{FS=":"} {print $1}'
    # head -n5 /etc/passwd | awk -F: '{print $1}'
    3.2、NR
    number of records:到当前行为止,总共处理的行数
    # head /etc/passwd | awk '{printf("%05d:: george--%s ",NR,$0)}' --NR统计总共处理的行数,通过%05d的格式输出
    # awk 'END{print NR}' /etc/passwd --直接用来计算总行数
    # awk -F: '{if (NR==1){print $1}}' /etc/passwd   --只处理第一行
    # awk -F ":" 'NR==2{print $1}' /etc/passwd  --输出文件第2行的第一列
    # awk -F ":" "NR==2{print $1}" /etc/passwd  --输出文件第2行的第一列
    3.3、FNR
    # ls -l /etc/ | sed 1d | awk 'BEGIN{print "start to process "} {total = total + $5} END{print NR " line Finished,resrlt: " total " kb"}' --初略计算 /etc 下的文件大小
    3.4、结合正则
    # ls -l | sed 1d | awk '{print $5,$0}' | sort -k1,1h | sed -r 's/^[^ ]+s*//' --将当前目录的文件按文件大小排列。[^ ]+表示多个非空,s 表示空格符
    3.5、实例
    # awk '{print $1}' access.log |sort|uniq -c|sort -nr|head -10 --分析access.log获得访问前10位的ip地址
     
    二、regular_expression
    1、正则表达式
    正则表达式是对字符串操作的一种逻辑公式;就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”,
    这个“规则字符串”用来表达对字符串的一种过滤逻辑;规定一些特殊语法表示字符类、数量限定符和位置关系,然后用这些特殊语法和普
    通字符一起表示一个模式,这就是正则表达式(Regular Expression)
    2、特点
    2.1、灵活性、逻辑性和功能性非常的强;
    2.2、可以迅速地用极简单的方式达到字符串的复杂控制。
    2.3、对于刚接触的人来说,比较晦涩难懂
    3、单字符表示法
    . --匹配任意字符
    d --匹配一个数字字符。等价于 [0-9]
    D --匹配一个非数字字符。等价于 [^0-9]
    f --匹配一个换页符。等价于 x0c 和 cL
    --匹配一个换行符。等价于 x0a 和 cJ
    --匹配一个回车符。等价于 x0d 和 cM
    s --匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ f v]
    S --匹配任何非空白字符。等价于 [^ f v]
    --匹配一个制表符。等价于 x09 和 cI
    v --匹配一个垂直制表符。等价于 x0b 和 cK
    w --匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'
     
    4、边界表示法
    ^ --字符串的开头
    $ --字符串的结尾
     --单词边界
    B --非单词边界
    < --单词左边界
    > --单词右边界
    5、分组表示法
    (abc) --一组连续的字符abc
    (aa|bb) --一组连续的字符ab 或者 bb
    6、字符集合
    [xyz] --字符集合。匹配所包含的任意一个字符
    [^xyz] --负值字符集合。匹配未包含的任意字符
    [a-z] --字符范围。匹配指定范围内的任意字符
    [^a-z] --负值字符范围。匹配任何不在指定范围内的任意字符
    7、数量表示法
    --用来表示前面的一个字符,或者一组字符重复的次数
    * --任意次, c >= 0
    + --至少1次, c >= 1
    ? --0次或者1次, c == 0 || c == 1
    {m} --m 次, c == m
    {m,} --至少m 次, c >= m
    {m,n} --m次 至 n次, c >= m && c <= n
    注意:默认情况下,数量表示符只作用于前面一个字符,若需要作用于前面多个字符,可以使用(...)把前面需要匹配的多个字符括起来
     
    8、特殊字符表示法
    ^ $ . * + ? | { } [ ] ( ) 都有特殊意义的,如果需要表示这些符号,则可以用反斜杠对它们进行转义
    9、引用表示法
    从左边开始数左边小括号,数字从1开始,被第一对括号匹配的字符可以用1 来引用,第二对可以用2 来引用,以此类推
    # echo abcabcabcaabb | grep -E '(a(bc)){2}1' --color
    # echo abcabcabcaabb | grep -E '(a(bc)){2}a2' --color
    # echo "hello world, hello world, hello beautiful world" | grep -E --color '((hello) (world)), 1, 2 .* 3'
    10、其他表示方法
    # date
    # date | grep --color -oE '([0-1][0-9]|2[0-3])(:[0-5][0-9]){2}' --时间表示
    # echo 2014-07-07 12:30:30 | grep --color -E '[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])' --日期表示
    # ifconfig | grep --color -E '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])' --IP地址表示
    # ifconfig | grep --color -E '([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}' --MAC表示
     
    三、测试
    1、获取eth0的IP地址
    # ifconfig eth0 | grep 'inet addr' | awk -F: '{print $2}' | awk '{print $1}'
    # ifconfig eth0 | grep 'inet addr' | sed 's/.*addr://;s/ .*//'
    2、查看root 用户的登录shell
    # grep ^root /etc/passwd | awk -F: '{print $NF}'
    3、查看/etc/passwd中有多少种登录shell
    # awk -F: '{print $NF}' /etc/passwd | sort -u | wc -l
    # sed 's/.*://' /etc/passwd | sort -u | wc -l
    4、计算多个文件的总行数/总大小
    # cat * | wc -l
    # cat * | wc -c
    5、计算字符串的长度
    # echo 123 | wc -c -- 多出的一个是换行符
    # echo -n 123 | wc -c -- 禁止输出换行符
    6、在文件第一行之前和最后一行之后输出一些字符
    # cat /etc/hosts | sed -e '1i ***********************' -e '$a ***********************'
    # cat /etc/hosts | awk 'BEGIN{print "xxxxxxx"} {print $0} END{print "xxxxxxx"}'
    7、输出系统开放的所有端口号
    # netstat -tulpn | awk '{print $4}' | awk -F: '{print $NF}' | grep [0-9] | sort -nu
    8、计算在线用户
    # who | wc -l
    9、历史开关机记录
    # last -x | grep -E 'reboot|shutdown'
    10、查根文件系统的可用空间
    # df -h | grep " /$" | awk '{print $(NF-2)}'
    11、查看sshd 登录记录,输出时间,用户名,客户端IP
    # grep -E 'sshd.*Accepted pub' /var/log/secure-20170528 | awk '{print $1,$2,$3,$9,$11}'
    12、系统至开机总运行时间
    # uptime | awk -F, '{print $1,$2}' | sed 's/.*up //' | tr -s " "
    13、将十进制 IP 地址转换为二进制的 IP 地址
    # echo 192.168.3.33 | sed -e 's/./;/g' -e 's/^/obase=2;ibase=10;/' | bc | xargs printf "%08d." | sed 's/.$/ /'
    # echo "obase=2;ibase=10;192;168;3;33" | bc | xargs printf "%08d." | sed 's/.$/ /'
    14、删除行首两个字符
    # sed 's/^..//'
    # tail -c +3
    15、删除行尾两个字符
    # sed 's/..$//'
    # head -c -2
    16、把字符串中的大写A替换成小写A
    # sed 's/A/a/g'
    # tr A a
    17、判断字符串是否以 A 开头
    if grep -Eq '^A'; then
    if [ "$(echo $str | sed 's/^A//')" != "$str" ];then
    if [ "${str#A}" != "$str" ]; then
    18、判断字符串是否以 A 结尾
    if grep -Eq 'A$'; then
    if [ "$(echo $str | sed 's/A$//')" != "$str" ];then
    if [ "${str%A}" != "$str" ]; then
    19、截取字符串前面两个字符
    # head -c 2
    # grep -oE '^..'
    # cut -c 1-2
    # sed -r 's/^(..).*$/1/'
    20、截取字符串后面两个字符
    # grep -oE '..$'
    # tail -c 2
    # sed -r 's/^.*(..)$/1/'
    21、截取字符串中第3至第5个字符
    # cut -c 3-5
    # sed -r 's/^..(...).*$/1/'
    # head -c5 | tail -c3
    22、截取字符串中第1,第3,第8至第10,第12至末尾的字符
    # cut -c1,3,8-10,12-
    # awk 'BEGIN{FS=""} { for(i=1;i<=NF;i++) {if (i==1 || i== 3 || (i>=8 && i<=10) || i>=12) print $i } }' | tr -d $' '
    23、去除数据中的重复行
    # sort -u
    # sort | uniq
    24、计算数据中相同的行出现的次数
    # sort | uniq -c
    25、进行大文件的切割,每个小文件为100M
    # head -c 2G /dev/urandom > bigfile
    # split -b104857600 bigfile bigfile_
    26、查找文件中单词 bin 出现的次数
    # grep -wo bin /etc/passwd | wc -l
    27、删除文件空白行
    # grep -vE '^$' /etc/ssh/sshd_config --不能删除有空格符的空白行
    # grep -vE '^s*$' /etc/ssh/sshd_config --可以删除有空格符的空白行
    28、把/etc/passwd 中所有的/bin/bash 登录shell 替换成 /sbin/nologin
    # sed -E 's#/bin/bash#/sbin/nologin#g' /etc/passwd
    29、统计文件 /etc/passwd 各个单词出现的频率
    # grep -oE 'w+' /etc/passwd | sort | uniq -c | sed -r 's/^ +//'
    # cat /etc/passwd | sed 's/[:/ ]/ /g' | sed '/^$/d' | sort | uniq -c | sed -E 's/^s+//' | sort -k1,1n
    # cat /etc/passwd | grep -Eo 'w+' | sort | uniq -c | sed -E 's/^s+//' | sort -k1,1n
    # cat /etc/passwd | sed 's/[:/ ]/ /g' | sed '/^$/d' | sort | uniq -c | sort -t" " -k6,6n
    30、字符串检测
    # echo abcd | grep -oE '^[a-z]+$' --测试字符串是否纯小写
    # echo 12344323 |grep -oE '^[0-9]+$' --测试字符串是否纯数字
    # echo iiiIIII | grep -oE '^[a-zA-Z]+$' --测试字符串是否纯字母
    # echo 3425 |grep -E '^(0|[1-9][0-9]*)$' --测试字符串是否非负整数
    # echo 3 |grep -E '^[1-9][0-9]*$' --测试字符串是否正整数
    # echo -23 |grep -E '^-[1-9][0-9]*$' --测试字符串是否负整数
    # echo 0 | grep -E '^(-[1-9][0-9]*)|(0|[1-9][0-9]*)$' --测试字符串是否整数
    # echo -0.30000 | grep -E '^(-[1-9][0-9]*|[+-]?0|[1-9][0-9]*).[0-9]+$' --测试字符串是否小数
    # echo _9kdj_324kdsd_dk | grep '^[a-zA-Z_][a-zA-Z0-9_]*$' --测试字符串是否只包含字母、数字、下划线,而且不以数字开头
     
  • 相关阅读:
    whatweb tree
    testUrl
    ParseUrl
    whatweb wordpress.rb
    LeetCode: Binary Tree Level Order Traversal 解题报告
    LeetCode: Minimum Path Sum 解题报告
    Lintcode: Sort Colors II 解题报告
    LeetCode: Validate Binary Search Tree 解题报告
    LeetCode: Longest Common Prefix 解题报告
    LeetCode: Maximum Subarray 解题报告
  • 原文地址:https://www.cnblogs.com/george-guo/p/7096179.html
Copyright © 2011-2022 走看看