Ⅰ. 概述
- grep是一个过滤器
- sed是一个流编辑器
- awk是报告生成器,对数据进行处理生成报告
Ⅱ. grep和egrep
egrep 是对 grep 的扩展
语法格式
- 第一种形式:
grep [option] [pattern] [file1, file2..]
- 第二种形式:
command | grep [option] [pattern]
grep参数
Ⅲ. sed
1. sed的工作模式
- sed(Stream Editor),流编辑器,对标准输出或文件逐行进行处理
语法格式
- 第一种:
stdout | sed [option] \"/pattern/command\"
或
stdout | sed [option] \"command\"
- 第二种:
sed [option] \"/pattern/command\" file
或
sed [option] \"command\" file
2. sed的选项
例子
p命令之所以显示两次是因为第一次是显示原行信息,第二次是命令的结果
-n
的作用
-e
的作用
[flw@nlp2 ~]$ sed -n -e \'/python/p\' -e \'/PYTHON/p\' sed.txtI love pythonI love PYTHON[flw@nlp2 ~]$
-f
的作用
[flw@nlp2 ~]$ cat edit.sed/python/p[flw@nlp2 ~]$ sed -n -f edit.sed sed.txtI love python[flw@nlp2 ~]$
-r
的作用
# \"|\" 是扩展正则表达式[flw@nlp2 ~]$ sed -n \'/python|PYTHON/p\' sed.txt[flw@nlp2 ~]$[flw@nlp2 ~]$[flw@nlp2 ~]$ sed -n -r \'/PYTHON|python/p\' sed.txtI love pythonI love PYTHON[flw@nlp2 ~]$
-i
的作用
-i最常用
[flw@nlp2 ~]$ sed -n \'s/love/like/g;p\' sed.txtI like pythonI like PYTHONHadoop is bigdataframe[flw@nlp2 ~]$ cat sed.txtI love pythonI love PYTHONHadoop is bigdataframe[flw@nlp2 ~]$[flw@nlp2 ~]$ sed -i \'s/love/like/g\' sed.txt[flw@nlp2 ~]$ cat sed.txtI like pythonI like PYTHONHadoop is bigdataframe[flw@nlp2 ~]$
3. sed中的pattern详解
4. sed中的编辑命令详解
例子
a
行后追加
i
行前追加
r
命令
w
命令
[flw@nlp2 ~]$ sed -n \'/\\/bin\\/bash/w /tmp/user.txt\' passwd
s
修改
格式 | 作用 |
---|---|
s/pattern/string/ | 查找符合pattern模式的字符串,将其替换为string。 同一行内,只替换第一个,等价于 s/pattern/string/1 |
s/pattern/string/g | 替换所有符合pattern模式的字符串 |
s/pattern/string/2 | 2: 同一行内,只替换前2个匹配的,剩下的不替换 |
s/pattern/string/2g | 2g: 同一行内,只替换从第2个开始往后的所有的匹配的字符串 |
s/pattern/string/ig | i: 表示匹配时忽略大小写 |
什么是反向引用
或者可以使用
sed -i \'s/\\(hermion.\\)/\\1s/g\' leihou,
\\1也可以表示反向引用,但是使用
\\1时前面必须加括号
\\1
和
&
的区别
seg 引用变量时的注意事项
- 匹配变量中如果存在变量,要使用双引号
[flw@nlp2 ~]$ old_string=\"hermionc\"[flw@nlp2 ~]$ new_string=\"hermione\"[flw@nlp2 ~]$ sed -i \"s/$old_string/$new_string/g\" leihou
- sed中需要引入自定义变量时,如果外面使用单引号,则自定义变量也必须使用单引号
[flw@nlp2 ~]$ sed -i \'s/\'$old_string\'/\'$new_string\'/g\' leihou
5. 利用sed查询特定内容
例子
对mysql的配置文件 my.cnf 进行处理
#!/bin/bashFILE_NAME=$PWD/my.cnf# 获取所有的段function get_all_segments{echo `sed -n \'/^\\[.*\\]/p\' $FILE_NAME | sed -e \'s/\\[//g\' -e \'s/\\]//g\'`}# 统计每一段中配置项的个数function count_items_in_segment{# grep -v \"^$\" 删除空行# grep -v \"^#\" 删除注释行items=`sed -n \"/^\\[$1\\]/,/^\\[.*\\]/p\" $FILE_NAME | grep -v \"^#\" | grep -v \"^$\" | grep -v \"^\\[.*\\]\"`index=0for item in $itemsdoindex=`expr $index + 1`doneecho $index}line=0for seg in `get_all_segments`doline=$(($line+1))sum=`count_items_in_segment $seg`echo \"$line $seg: $sum\"done
my.cnf如下所示:
[client]port=3306socket=/tmp/mysql.socket#ThisSegmentForserver[server]innodb_buffer_pool_size=91750Minnodb_buffer_pool_instances=8innodb_buffer_pool_load_at_startup=1innodb_buffer_pool_dump_at_shutdown=1innodb_data_file_path=ibdata1:1G:autoextendinnodb_flush_log_at_trx_commit=1innodb_log_buffer_size=32Minnodb_log_file_size=2Ginnodb_log_files_in_group=2innodb_max_undo_log_size=4Ginnodb_undo_directory=undologinnodb_undo_tablespaces=95#thisisonlyforthemysqldstandalonedaemon[mysqld]port=3306socket=/tmp/mysql.sockbasedir=/usr/local/mysqldatadir=/data/mysqlpid-file=/data/mysql/mysql.piduser=mysqlbind-address=0.0.0.0sort_buffer_size=16Mjoin_buffer_size=16Mthread_cache_size=3000interactive_timeout=600wait_timeout=600#ThisSegmentFormysqld_safe[mysqld_safe]log-error=/var/log/mariadb/mariadb.logpid-file=/var/run/mariadb/mariadb.pidmax_connections=1000open_files_limit=65535thread_stack=512Kexternal-locking=FALSEmax_allowed_packet=32M#thisisonlyforembeddedserver[embedded]gtid_mode=onenforce_gtid_consistency=1log_slave_updatesslave-rows-search-algorithms=\'INDEX_SCAN,HASH_SCAN\'binlog_format=rowbinlog_checksum=1relay_log_recovery=1relay-log-purge=1#usethisgroupforoptionsthatolderserversdon\'tunderstand[mysqld-5.5]key_buffer_size=32Mread_buffer_size=8Mread_rnd_buffer_size=16Mbulk_insert_buffer_size=64Mmyisam_sort_buffer_size=128Mmyisam_max_sort_file_size=10Gmyisam_repair_threads=1lock_wait_timeout=3600explicit_defaults_for_timestamp=1innodb_file_per_table=1
结果如下所示:
[flw@nlp2 67]$ sh mysql_process.sh1 client: 22 server: 123 mysqld: 124 mysqld_safe: 75 embedded: 86 mysqld-5.5: 10
6. 利用sed删除文件内容
删除/etc/passwd中以yarn开头的行到最后的所有行
sed -i \'/^yarn/,$d\' passwd
删除配置文件中的所有注释行(#前面可能有空格)
sed -i \'/\\d*#/d\' nginx.conf
7, 利用sed修改文件内容
7. 利用sed追加文件内容
a
在第10行到第20行,每行后(后面一行)追加 “leihou”
sed -i \'10,20a leihou\' passwd
i
匹配到以yarn开头的行,在匹配行前面(前面一行)追加 “alielie”
sed -i \'/^yarn/i alielie\' passwd
r
将/etc/fstab文件的内容追加到passwd文件的第20行后面
sed -i \'20r /etc/fstab\' passwd
w
将passwd文件匹配到/bin/bash的行追加到/tmp/sed.txt文件中
sed -i \'/\\/bin\\/bash/w /tmp/sed.txt\' passwd
Ⅲ awk
1. awk工作模式介绍
awk是一个文本处理工具,通常用于处理数据并生成结果报告。
语法格式
- 第一种:
awk \'BEGIN{}[pattern]{commands}END{}\' file_name
- 第二种:
standard output | awk \'BEGIN{}[pattern]{commands}END{}\'
[] 代表可以不写
语法格式说明
语法格式 | 解释 |
---|---|
BEGIN{} | 正式处理数据之前执行 |
pattern | 匹配模式,可以不写 |
{commands} | 处理命令,可能多行 |
END{} | 处理完所有匹配数据后执行 |
2. awk的内置变量
例子:
$0, $1
[flw@nlp2 72]$ awk \'{print $0}\' passwdroot:x:0:0:root:/root:/bin/bashbin:x:1:1:bin:/bin:/sbin/nologin[flw@nlp2 72]$[flw@nlp2 72]$ awk \'BEGIN{FS=\":\"}{print $1}\' passwd # FS=\":\" 分隔符是:rootbin[flw@nlp2 72]$
NF
[flw@nlp2 72]$ cat listHadoop Spark FlumeJava Python JavaScript GoHermione Harry Voldemort[flw@nlp2 72]$[flw@nlp2 72]$ awk \'{print $1}\' list # 默认是以空格或者TAB为分隔符HadoopJavaHermione[flw@nlp2 72]$[flw@nlp2 72]$ awk \'{print NF}\' list # 输出每一行字段个数343[flw@nlp2 72]$
NR, FNR
[flw@nlp2 72]$ awk \'{print NR}\' list passwd # 行号12345[flw@nlp2 72]$[flw@nlp2 72]$ awk \'{print FNR}\' list passwd # 行号,每个文件单独记数12312
FS, RS
默认以 空格 或 TAB 为分隔符
[flw@nlp2 72]$ cat list2Hadoop|Sparkr:Flume--Java|Pythonr:JavaScript:Go--Hermione|Harry:Voldemort[flw@nlp2 72]$[flw@nlp2 72]$ awk \'BEGIN{FS=\":\";RS=\"--\"}{print $2}\' list2FlumeJavaScriptVoldemort[flw@nlp2 72]$ awk \'BEGIN{FS=\":\";RS=\"--\"}{print $1}\' list2Hadoop|SparkrJava|PythonrHermione|Harry[flw@nlp2 72]$
OFS, ORS
FILENAME
[flw@nlp2 72]$ cat listHadoop Sparkr FlumeJava Pythonr JavaScript GoHermione Harry Voldemort[flw@nlp2 72]$[flw@nlp2 72]$[flw@nlp2 72]$ awk \'{print FILENAME}\' listlistlistlist
3. awk格式化输出printf
printf的格式说明符
最常用的是前两种。
printf的修饰符
例子
# %-20s: \"-\"左对齐; 20表示字符串的长度是20[flw@nlp2 72]$ awk \'BEGIN{FS=\":\"}{printf \"%-20s %-20s-\\n\", $1, $2}\' passwdroot x -bin x -[flw@nlp2 72]$
4. awk模式匹配的两种用法
- 第一种模式匹配:RegExp(正则表达式)
- 第二种模式匹配:关系运算匹配
例子
1. 正则表达式
匹配 /etc/passwd 文件行中含义root字符串的所有行
awk \'/root/{print $0}\' passwd
匹配 /etc/passwd 文件行中以yarn开头的所有行
awk \'/^yarn/{print $0}\' passwd
2. 关系运算
以:为分隔符,匹配 /etc/passwd 文件中第3个字段小于50的所有行信息
awk \'BEGIN{FS=\":\"}$3<50{print $0}\' passwd
以:为分隔符,匹配 /etc/passwd 文件中第3个字段等于/bin/bash的所有行信息
awk \'BEGIN{FS=\":\"}$7==\"/bin/bash\"{print $0}\' passwd
以:为分隔符,匹配 /etc/passwd 文件中第3个字段为包含3个以上数字的所有行信息
awk \'BEGIN{S=\":\"}$3~/[0-9]{3,}/{print $0}\' passwd
以:为分隔符,匹配 /etc/passwd 文件中第1个字段为root或者bin的所有行信息
awk \'BEGIN{FS=\":\"}$1==\"root\"||$1==\"bin\"{print $0}\' passwd
以:为分隔符,匹配 /etc/passwd 文件中第3个字段小于50且第4个字段大于59的所有行信息
awk \'BEGIN{FS=\":\"} $3<50 && $4>50 {print $0}\' passwd
5. awk中表达式的用法
[flw@nlp2 72]$ awk \'BEGIN{var=20;var1=\"hello\";print var, var1}\'20 hello[flw@nlp2 72]$
计算passwd中的空白行数量
awk \'/^$/{sum++}END{print sum}\' passwd
计算学生课程分数平均值
[flw@nlp2 76]$ cat txt蓉儿 80 90 96 98盈盈 93 98 92 91赵敏 85 95 75 90赫敏 78 88 98 100[flw@nlp2 76]$[flw@nlp2 76]$[flw@nlp2 76]$ awk \'BEGIN{printf \"%-16s%-16s%-16s%-16s%-16s%-16s\\n\", \"name\", \"chinese\", \"english\", \"math\", \"physics\", \"average\"}{sum=$2+$3+$4+$5;ave=sum/4;printf \"%-16s%-16s%-16s%-16s%-16s%-16s\\n\", $1, $2, $3, $4, $5, ave}\' txtname chinese english math physics average蓉儿 80 90 96 98 91盈盈 93 98 92 91 93.5赵敏 85 95 75 90 86.25赫敏 78 88 98 100 91[flw@nlp2 76]$
6. awk动作中的条件及循环语句
6.1 条件语句
例子
1
以:为分隔符,只打印/etc/passwd中第3个字符案的数值在50-100范围内的行信息
awk \'BEGIN{FS=\":\"}$3>=50 && $3<=100{print $0}\' passwd# 或者awk \'BEGIN{FS=\":\"}{if($3>=50 && $3<=100) print $0}\' passwd
2
以:为分隔符,以:为分隔符,只打印/etc/passwd中第3个字符案的数值小于50或者大于100的行信息
awk \'BEGIN{FS=\":\"}{if($3<50){ printf \"%-10s%-5d\\n\", \"小于50:\", $3} else if($3>100) {printf \"%-10s%-5d\\n\", \"大于100:\", $3}}\' passwd
或者可以把配置项写在文件中,如下:
6.2 循环语句
6.2.1 while循环
6.2.2 do-while循环
6.2.3 for循环
6.2.4 例子
1
计算1+2+…+100的和
[flw@nlp2 78]$ cat while.awkBEGIN{while(i<=100) {sum += ii++}print sum}[flw@nlp2 78]$[flw@nlp2 78]$[flw@nlp2 78]$ awk -f script1.awk passwd5050[flw@nlp2 78]$
计算每门课的平均成绩
[flw@nlp2 78]$ cat student.awkBEGIN{score_chinese=0score_english=0score_math=0score_physics=0count=0printf \"%-16s%-16s%-16s%-16s%-16s\\n\", \"name\", \"chinese\", \"english\", \"math\", \"physics\"}{score_chinese+=$2score_english+=$3score_math+=$4score_physics+=$5count++printf \"%-16s%-16s%-16s%-16s%-16s\\n\", $1, $2, $3, $4, $5}END{score_chinese/=countscore_english/=countscore_math/=countscore_physics/=countprintf \"%-16s%-16s%-16s%-16s%-16s\\n\", \"平均\", score_chinese, score_english, score_math, score_physics}[flw@nlp2 78]$[flw@nlp2 78]$[flw@nlp2 78]$ awk -f student.awk txtname chinese english math physics蓉儿 80 90 96 98盈盈 93 98 92 91赵敏 85 95 75 90赫敏 78 88 98 100平均 84 92.75 90.25 94.75[flw@nlp2 78]$
7. awk中的字符串函数
例子
以:为分隔符,返回/etc/passwd中每行中每个字段的长度
[flw@nlp2 79]$ cat e1.awkBEGIN{FS=\":\"}{for(i=1;i<=NF;i++) {if (i!=NF) {printf \"%d:\", length($i)}else {printf \"%d\", length($i)}}print \"\" # print 自带换行}[flw@nlp2 79]$[flw@nlp2 79]$ awk -f e1.awk passwd4:1:1:1:4:5:93:1:1:1:3:4:13# ..[flw@nlp2 79]$
搜索字符串 “I have a dream” 中出现 “ea” 字符串的位置
[flw@nlp2 79]$ awk \'BEGIN{printf \"%d\\n\", index(\"I have a dream\", \"ea\")}\' # 起始位置是112# 或者[flw@nlp2 79]$ awk \'BEGIN{printf \"%d\\n\", match(\"I have a dream\", \"ea\")}\'
将字符串 “Hadoop is a bigdata Framework” 全部 转换为大写
[flw@nlp2 79]$ awk \'BEGIN{printf \"%s\\n\", tolower(\"Hadoop is a bigdata Framework\")}\'hadoop is a bigdata framework
将字符串 “蓉儿 盈盈 赵敏 赫敏” 按空格分隔,分隔后每部分保存到数组array中
[flw@nlp2 79]$ awk \'BEGIN{split(\"蓉儿 盈盈 赵敏 赫敏\", arr, \" \"); print arr[0]}\'[flw@nlp2 79]$ awk \'BEGIN{split(\"蓉儿 盈盈 赵敏 赫敏\", arr, \" \"); print arr[1]}\'蓉儿[flw@nlp2 79]$
awk 中数组和字符串的下标都是从1开始记数
搜索字符串 “Tranction 2345 start:Select * from master” 中第一个数字出现的位置
[flw@nlp2 79]$ awk \'BEGIN{printf \"%d\\n\", match(\"Tranction 2345 start:Select * from master\", /[0-9]/)}\'11[flw@nlp2 79]$
在sed和awk中,如果要使用正则表达式,必须使用
/RegEpr/这种形式
截取字符串 “transaction start” 的子串,截取条件从第4个字符开始,截取5位
[flw@nlp2 79]$ awk \'BEGIN{printf \"%s\\n\", substr(\"transaction start\", 4, 5)}\'nsact
替换字符串 “Transaction 243 Start, Event ID:9002” 中第一个匹配到的数字串为 $ 符号
[flw@nlp2 79]$ awk \'BEGIN{a=\"Transaction 243 Start, Event ID:9002\";sub(/[0-9]+/, \"$\", a);printf \"%s\\n\", a}\'Transaction $ Start, Event ID:9002[flw@nlp2 79]$ awk \'BEGIN{a=\"Transaction 243 Start, Event ID:9002\";gsub(/[0-9]+/, \"$\", a);printf \"%s\\n\", a}\'Transaction $ Start, Event ID:$
8. awk中的常用选项
1. -v
[flw@nlp2 79]$ num1=20[flw@nlp2 79]$ var=\"leihou\"[flw@nlp2 79]$[flw@nlp2 79]$[flw@nlp2 79]$ awk -v num2=\"$num1\" -v var1=\"$var\" \'BEGIN{printf \"%d--%s\\n\", num2, var1}\'20--leihou[flw@nlp2 79]$
2. -F
[flw@nlp2 79]$ awk \'BEGIN={FS=\":\"}{print $1}\' passwd# 等价于[flw@nlp2 79]$ awk -F \":\" \'{print $1}\' passwd
9. awk中数组的用法
例子
- 统计主机上所有的TCp连接,并统计不同状态的连接数
netstat -ntlp | grep tcp | awk \'{array[$6]++}END{for (a in array) {printf \"%-10s%-10s\\n\",a, array[a]}}\'