Ⅰ. 概述
- 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.txt
I love python
I love PYTHON
[flw@nlp2 ~]$
-f
的作用
[flw@nlp2 ~]$ cat edit.sed
/python/p
[flw@nlp2 ~]$ sed -n -f edit.sed sed.txt
I 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.txt
I love python
I love PYTHON
[flw@nlp2 ~]$
-i
的作用
-i
最常用
[flw@nlp2 ~]$ sed -n 's/love/like/g;p' sed.txt
I like python
I like PYTHON
Hadoop is bigdataframe
[flw@nlp2 ~]$ cat sed.txt
I love python
I love PYTHON
Hadoop is bigdataframe
[flw@nlp2 ~]$
[flw@nlp2 ~]$ sed -i 's/love/like/g' sed.txt
[flw@nlp2 ~]$ cat sed.txt
I like python
I like PYTHON
Hadoop 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/bash
FILE_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=0
for item in $items
do
index=`expr $index + 1`
done
echo $index
}
line=0
for seg in `get_all_segments`
do
line=$(($line+1))
sum=`count_items_in_segment $seg`
echo "$line $seg: $sum"
done
my.cnf如下所示:
[client]
port=3306
socket=/tmp/mysql.socket
#ThisSegmentForserver
[server]
innodb_buffer_pool_size=91750M
innodb_buffer_pool_instances=8
innodb_buffer_pool_load_at_startup=1
innodb_buffer_pool_dump_at_shutdown=1
innodb_data_file_path=ibdata1:1G:autoextend
innodb_flush_log_at_trx_commit=1
innodb_log_buffer_size=32M
innodb_log_file_size=2G
innodb_log_files_in_group=2
innodb_max_undo_log_size=4G
innodb_undo_directory=undolog
innodb_undo_tablespaces=95
#thisisonlyforthemysqldstandalonedaemon
[mysqld]
port=3306
socket=/tmp/mysql.sock
basedir=/usr/local/mysql
datadir=/data/mysql
pid-file=/data/mysql/mysql.pid
user=mysql
bind-address=0.0.0.0
sort_buffer_size=16M
join_buffer_size=16M
thread_cache_size=3000
interactive_timeout=600
wait_timeout=600
#ThisSegmentFormysqld_safe
[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid
max_connections=1000
open_files_limit=65535
thread_stack=512K
external-locking=FALSE
max_allowed_packet=32M
#thisisonlyforembeddedserver
[embedded]
gtid_mode=on
enforce_gtid_consistency=1
log_slave_updates
slave-rows-search-algorithms='INDEX_SCAN,HASH_SCAN'
binlog_format=row
binlog_checksum=1
relay_log_recovery=1
relay-log-purge=1
#usethisgroupforoptionsthatolderserversdon'tunderstand
[mysqld-5.5]
key_buffer_size=32M
read_buffer_size=8M
read_rnd_buffer_size=16M
bulk_insert_buffer_size=64M
myisam_sort_buffer_size=128M
myisam_max_sort_file_size=10G
myisam_repair_threads=1
lock_wait_timeout=3600
explicit_defaults_for_timestamp=1
innodb_file_per_table=1
结果如下所示:
[flw@nlp2 67]$ sh mysql_process.sh
1 client: 2
2 server: 12
3 mysqld: 12
4 mysqld_safe: 7
5 embedded: 8
6 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}' passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[flw@nlp2 72]$
[flw@nlp2 72]$ awk 'BEGIN{FS=":"}{print $1}' passwd # FS=":" 分隔符是:
root
bin
[flw@nlp2 72]$
NF
[flw@nlp2 72]$ cat list
Hadoop Spark Flume
Java Python JavaScript Go
Hermione Harry Voldemort
[flw@nlp2 72]$
[flw@nlp2 72]$ awk '{print $1}' list # 默认是以空格或者TAB为分隔符
Hadoop
Java
Hermione
[flw@nlp2 72]$
[flw@nlp2 72]$ awk '{print NF}' list # 输出每一行字段个数
3
4
3
[flw@nlp2 72]$
NR, FNR
[flw@nlp2 72]$ awk '{print NR}' list passwd # 行号
1
2
3
4
5
[flw@nlp2 72]$
[flw@nlp2 72]$ awk '{print FNR}' list passwd # 行号,每个文件单独记数
1
2
3
1
2
FS, RS
默认以 空格 或 TAB 为分隔符
[flw@nlp2 72]$ cat list2
Hadoop|Sparkr:Flume--Java|Pythonr:JavaScript:Go--Hermione|Harry:Voldemort
[flw@nlp2 72]$
[flw@nlp2 72]$ awk 'BEGIN{FS=":";RS="--"}{print $2}' list2
Flume
JavaScript
Voldemort
[flw@nlp2 72]$ awk 'BEGIN{FS=":";RS="--"}{print $1}' list2
Hadoop|Sparkr
Java|Pythonr
Hermione|Harry
[flw@nlp2 72]$
OFS, ORS
FILENAME
[flw@nlp2 72]$ cat list
Hadoop Sparkr Flume
Java Pythonr JavaScript Go
Hermione Harry Voldemort
[flw@nlp2 72]$
[flw@nlp2 72]$
[flw@nlp2 72]$ awk '{print FILENAME}' list
list
list
list
3. awk格式化输出printf
printf的格式说明符
最常用的是前两种。
printf的修饰符
例子
# %-20s: "-"左对齐; 20表示字符串的长度是20
[flw@nlp2 72]$ awk 'BEGIN{FS=":"}{printf "%-20s %-20s-\n", $1, $2}' passwd
root 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}' txt
name 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.awk
BEGIN{
while(i<=100) {
sum += i
i++
}
print sum
}
[flw@nlp2 78]$
[flw@nlp2 78]$
[flw@nlp2 78]$ awk -f script1.awk passwd
5050
[flw@nlp2 78]$
计算每门课的平均成绩
[flw@nlp2 78]$ cat student.awk
BEGIN{
score_chinese=0
score_english=0
score_math=0
score_physics=0
count=0
printf "%-16s%-16s%-16s%-16s%-16s\n", "name", "chinese", "english", "math", "physics"
}
{
score_chinese+=$2
score_english+=$3
score_math+=$4
score_physics+=$5
count++
printf "%-16s%-16s%-16s%-16s%-16s\n", $1, $2, $3, $4, $5
}
END{
score_chinese/=count
score_english/=count
score_math/=count
score_physics/=count
printf "%-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 txt
name 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.awk
BEGIN{
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 passwd
4:1:1:1:4:5:9
3: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")}' # 起始位置是1
12
# 或者
[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]}}'