1、总结sed和awk的详细用法;
sed Sed本质上是一个编辑器,但是它是非交互式的;同时它又是面向字符流的,输入的字符流经过sed的处理后输出。 Sed本身是一个管道命令,可以分析standard input的,主要是用来分析关键字的使用、统计等,此外还可以将数据进行替换、删除、 选取特定行等功能 格式:sed [option] ... 'script' inputfile... script: '地址命令' 常用选项: -n:不输出模式中的内容至屏幕,只列出经过sed处理过的那一行。 -e:多点编辑,直接在命令行模式上进行sed的动作编辑。 -f:将sed的动作写在一个文件内,-f filename则可以执行filename内的sed 动作。 -r:支持使用扩展正则表达式; -i:直接修改读取的文件内容,而不是由屏幕输出。 地址定界: (1)不给地址:对全文进行处理; (2)单地址: #:指定的行; /pattern/:被此处模式所能够匹配到的每一行; (3)地址范围: #,# #,+# /part1/,/part2/ 编辑命令: d:删除 p:显示模式空间中的内容 a \text:在行后面追加文本;支持使用\n实现多行追加; i \text:在行前面插入文本;支持使用\n实现多行插入; c \text:替换行为单行或多行文本; w /path/to/somefile:保存模式空间匹配到的行至指定文件中; r /path/from/some:读取指定文件的文本流至模式空间中匹配到的行的行后; =:为模式空间中的行打印行号; !:取反条件; s///:支持使用其它分隔符,s@@@,S###; 替换标记: g:行内全局替换; p:显示替换成功的行; w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中; 常用案例 以行为单位的新增加删除功能 1、nl /etc/passwd | sed '2,5d' 说明: sed的动作为'2,5d',d就是删除,命令运行的结果就是把2~5行给删除。 sed后面接的动作,必须以''两个单引号括住。 如果只想删除第二行,命令就是nl /etc/passwd | sed '2d' 如果想删除第2行到最后一行,可以这么写:nl /etc/passwd | sed '2,$d' 2、nl /etc/passwd | sed '2a play game' 说明: 命令执行效果就是在第二行后面(也就是第三行)加上“play game”字样 如果想在第二行前面加上字符器,可以这样: nl /etc/passwd | sed '2i play game' 注:2a中的a追加的意思,指第二行后面,而2i中的i是插入的意思,指第二行的前面。 3、nl /etc/passwd | sed '2a play game or ...\nplay football' 说明: 命令执行结果是在第二行后面加入2行字。 在每一行的后面必须以\n来进行新行的增加 以行为单位的替换与显示功能 1、nl /etc/passwd | sed '2,5c No 2~5 number' 说明: 命令的执行效果是将第2~5行的内容替换成"No 2~5 number" 2、nl /etc/passwd | sed -n '5,7p' 说明: 命令的执行效果是仅打印出文件中的第5~7行 命令中的-n代表是的安静模式! 3、sed 's/要被替换的内容/新内容/g' 说明: 命令执行的效果就是替换掉指定内容 4、记录一次获取IP地址的过程 第一步:先查询IP /sbin/ifconfig eth0 注:目的是要获取IP数据,那么先利用关键字找出那一行 第二步:利用关键字配置grep选取出关键的一行数据 /sbin/ifconfig eth0 | grep 'inet addr' 注:因为只需要IP数据,所以接下来就是把不需要的内容删除,需要一个正则表达式来帮助实现: ^.*inet addr 第三步:将IP前面的部分予以删除 /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*inet addr://g' 注:上面的命令就是把IP前面的数据删除掉了,接下来就是把IP后面的数据也删除,此时的正则表达式是: Bcast.*$ 第四步:将IP后面的部分予以删除 /sbin/ifconfig eth0 | grep 'inet addr' | sed 's/^.*inet addr://g' | sed 's/Bcast.*$//g' 这样就把IP地址截取出来了。 直接修改文件内容(慎重) 1、sed -i '$a #This is a test' test.txt 说明: 命令的执行结果是在test.txt最后一行加入“This is a test” 由于$代表的是最后一行,而a的操作是新增,因此该文件最后新增。 awk 功能:awk是一个数据处理工具。相比于sed常常用于一整行的处理,awk则比较倾向于将一行分成数个“字段”来处理。因此,awk相当 适合处理小型数据的数据处理。 基本语法: awk [options] 'program' FILE ... program:PATTERN {ACTION STATEMENTS} 多个语句之间用分号分隔 print,printf 选项: -F:指明输入时用到的字段分隔符; -v var=value:自定义变量; 1、print print item1, item2, ... 要点: (1)逗号分隔符; (2)输出的各item可以是字符串,也可以是数值;当前记录的字段、变量或awk的表达式; (3)如省略item,相当于print $0; 2、变量 (1)内建变量 FS:input field seperator,输入分隔符,默认为空白字符; OFS:output field seperator,输出分隔符,默认为空白字符; RS:input record sepeator,输入时的换行符; ORS:output record seperator,输出时的换行符; NF:number of field,字段数量 {print NF}, {print $NF} NR:number of record,行数; FNR:各文件分别计数;行数; FILENAME:当前文件名; ARGC:命令行参数的个数; ARGV:数组,保存的是命令行所给定的各参数; (2)自定义变量 -v var=value 变量名区分字符大小写 在program中直接定义 3、printf命令 格式化输出:printf FORMAT, item1, item2, ... (1)FORMAT必须给出; (2)不会自动换行,需要显式给出换行控制符,\n (3)FORMAT中需要分别为后面的每个item指定一个格式化符号; 格式符: %c:显示字符的ASCII码; %d,%i:显示十进制整数; %e,%E:科学计数法数值显示; %f:显示为浮点数; %g,%G:以科学计数或浮点形式显示数值; %s:显示字符串; %u:无符号整数; %%:显示%自身; 修饰符: #[.#]:第一个数字控制显示的宽度;第二个#表示小数点后的精度; %3.1f -:左对齐 +:显示数值的符号 4、PATTERN (1)empty:空模式,匹配每一行; (2)/regular expression/:仅处理能够被此处模式匹配到的行; (3)relational expression:关系表达式;结果有“真”有“假”;结果为“真”才会被处理 真:结果为非0值,非空字符串; (4)line ranges:行范围, startline,endline:/pat1/,/pat2/ 注意:不支持直接给出数字的格式 (5)BEGIN/END模式 BEGIN{}:仅在开始处理文件中的文本之前执行一次; END{}:仅在文本处理完成之后执行一次; 5、常用的action (1)Expressions (2)Control statements:if,while等; (3)Compound statements:组合语句; (4)input statements (5)output statements 6、控制语句 (1)if-else 语法:if(condition) statement [else statement] 使用场景:对awk取得的整行或某个字段做条件判断; 示例: awk -F: '{if($3>=500) {printf "Common user:%s\n",$1} else {printf "root or Sysuser:%s\n",$1}}' /etc/passwd awk -F: '{if($NF=="/bin/bash") print $1}' /etc/passwd awk '{if(NF>5) print $0}' /etc/fstab df -h | awk -F% '/^\/dev/{print $1}' | awk '{if($NF>=20) print $1}' (2)while循环 语法:while(condition) statement 条件 “真”,进行循环;条件“假”,退出循环; 使用场景:对一行内的多个字段逐一类似处理时使用;对数组中的各元素逐一处理时使用; 示例: awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {print $i,length($i); i++}}' /etc/grub2.cfg awk '/^[[:space:]]*linux16/{i=1;while(i<=NF) {if(length($i)>=7){print $i,length($i)}; i++}}' /etc/grub2.cfg (3)do-while循环 语法:do statement while(condition) 意义:至少执行一次循环体 (4)for循环 语法:for(expr1;expr2;expr3) statement for(variable assignment;condition;iteration process){for-body} 示例: awk '/^[[:space:]]*linux16/{for(i=1;i<=NF;i++){print $i,length($i)}}' /etc/grub2.cfg 特殊用法: 能够遍历数组中的元素; 语法:for(var in array){for-body} (5)switch语句 语法:switch(expression) {case VALUE1 or /REGEXP/:statement;case VALUE2 or /REGEXP2/:statement;...;default:statement} (6)next 提前结束对本行的处理而直接进入下一行; 示例: awk -F: '{if($3%2!=0)next;print $1,$3}' /etc/passwd 7、array 关联数组:array[index-expression] index-expression: (1)可使用任意字符串,字符串要使用双引号; (2)如果某数组元素事先不存在,在引用时,awk会自动创建此元素,并将其值初始化为“空串”; 若要判断数组中是否存在某元素,使用“index in array”格式进行; weekdays[mon]="Monday" 若要遍历数组中的每个元素,要使用for循环; for(var in array){for-body} 示例: awk 'BEGIN{weekdays["mon"]="Monday";weekdays["tue"]="Tuesday";for(i in weekdays){print weekdays[i]}}' 8、其它常见示例 (1)统计/etc/fstab文件中每个文件系统类型出现的次数; awk '/^UUID/{fs[$3]++}END{for(i in fs){print i,fs[i]}}' /etc/fstab (2)统计/etc/fstab文件中每个单词出现的次数; awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count){print i,count[i]}}' /etc/fstab
2、删除/boot/grub/grub.conf文件中所有行的行首的空白字符;
[root@localhost ~]# sed 's/^[[:space:]]*//g' /boot/grub/grub.conf
3、删除/etc/fstab文件中所有以#开头,后跟至少一个空白字符的行的行首的#和空白字符;
[root@localhost ~]# sed 's/^#[[:space:]]\+//' /etc/fstab
4、把/etc/fstab文件的奇数行另存为/tmp/fstab.3;
[root@localhost ~]# sed 'n;d' /etc/fstab > /etc/fstab.3
5、echo一个文件路径给sed命令,取出其基名;进一步地,取出其路径名;
[root@localhost ~]# echo "/etc/sysconfig/network/" | sed -r 's@^/.*/([^/]+)/?@\1@g' [root@localhost ~]# echo "/etc/sysconfig/network/" | sed 's#[^/]\+/\?$##'
6、统计指定文件中所有行中每个单词出现的次数;
[root@localhost ~]# awk '{for(i=1;i<=NF;i++){count[$i]++}}END{for(i in count){print i,count[i]}}' /etc/fstab
7、统计当前系统上所有tcp连接的各种状态的个数;
[root@localhost ~]# netstat -tan | awk 'FNR>2{print $NF}' | sort | uniq -c
8、统计指定的web访问日志中各ip的资源访问次数:
[root@localhost ~]# awk '{ip[$1]++}END{for(i in ip) {print i,ip[i]}}' /var/log/httpd/access_log
9、写一个脚本:定义一个数组,数组元素为/var/log目录下所有以.log结尾的文件的名字;显示每个文件的行数;
[root@localhost ~]# vim line.sh #!/bin/bash test=`ls /var/log/*log` for i in $test do wc -l $i done
10、写一个脚本,能从所有同学中随机挑选一个同学回答问题;进一步地:可接受一个参数,做为要挑选的同学的个数;
[[root@localhost ~]# vim student.sh #!/bin/bash stu=(zhangsan lisi wangwu zhaoliu liuhu zhaosi) i=$[$RANDOM % ${#stu[@]}] echo ${stu[i]} [root@localhost ~]# vim students.sh #!/bin/bash stu=(zhangsan lisi wangwu zhaoliu liuhu zhaosi) read -p "Please input the number of students:" num if [[ $num -le ${#stu[@]} ]] then for ((i=0;i<num;i++)) do x=$[$RANDOM % ${#stu[@]}] echo ${stu[$x]} stu[$x]=${stu[${#stu[@]}-1]} unset stu[${#stu[@]}-1] done else echo "input error!" fi
11、授权centos用户可以运行fdisk命令完成磁盘管理,以及使用mkfs或mke2fs实现文件系统管理;
[root@localhost ~]# vim /etc/sudoers centos ALL=(root) NOPASSWD: /sbin/fdisk, /sbin/mke2fs, /sbin/mkfs
12、授权gentoo用户可以运行逻辑卷管理的相关命令;
[root@localhost ~]# vim /etc/sudoers gentoo ALL=(root) lvm
13、基于pam_time.so模块,限制用户通过sshd服务远程登录只能在工作时间进行;
[root@localhost ~]# vim /etc/pam.d/sshd account required pam_time.so [root@localhost ~]# vim /etc/security/time.conf *;*;*;MoTuWeThFr0900-1800#表示工作时间9点到下午6点允许访问ssh
14、基于pam_listfile.so模块,定义仅某些用户,或某些组内的用户可登录系统;"
[root@localhost ~]# vim /etc/sshd_userlist root centos gentoo [root@localhost ~]# chmod 600 /etc/sshd_userlist [root@localhost ~]# chown root /etc/sshd_userlist [root@localhost ~]# vim /etc/pam.d/sshd 添加 auth required pam_listfile.so item=user sense=allow file=/etc/sshd_userlist onerr=succeed
原创文章,作者:N21-天天,如若转载,请注明出处:http://www.178linux.com/61536