美文网首页
7、文本处理三剑客

7、文本处理三剑客

作者: 一个反派人物 | 来源:发表于2020-11-06 11:13 被阅读0次

1 grep、egrep

过滤关键字行

grep [OPTION]... PATTERN [FILE]...
#以下参数常用
-i #忽略大小写
-w #整词匹配
-E #使用扩展正则表达式
-A #显示匹配行的前NUM行
-B #显示匹配行的后NUM行
-C #显示匹配行的前后NUM行
Regexp selection and interpretation:
  -E, --extended-regexp     PATTERN is an extended regular expression (ERE)
  -F, --fixed-strings       PATTERN is a set of newline-separated fixed strings
  -G, --basic-regexp        PATTERN is a basic regular expression (BRE)
  -P, --perl-regexp         PATTERN is a Perl regular expression
  -e, --regexp=PATTERN      use PATTERN for matching
  -f, --file=FILE           obtain PATTERN from FILE
  -i, --ignore-case         ignore case distinctions  #忽略大小写
  -w, --word-regexp         force PATTERN to match only whole words
  -x, --line-regexp         force PATTERN to match only whole lines
  -z, --null-data           a data line ends in 0 byte, not newline
  -c, --count               print only a count of matching lines per FILE   #计数
  -v, --invert-match        select non-matching lines      #取反
  -o, --only-matching       show only the part of a line matching PATTERN  #只显示匹配的部分,而不是显示匹配的整行
  -r, --recursive           like --directories=recurse    #递归查找文件夹
Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context

2 sed、sed -r

基本用法

sed [OPTION]... {script-only-if-no-other-script} [input-file]...
(1)读取一行至内存空间
(2)使用内存空间中的内容,进行条件判断并执行处理
(3)打印处理后的行,如果不符合条件,则打印的是原行
(4)继续读取第二行
语法顺序:sed 参数 '条件-处理' 文件名

2.1 参数

-e 多个'条件-处理'语句,前面用-e参数分别执行
-i 将改动写入到文件,同时停止默认打印
-i.bak 将原文件备份为.bak,然后将改动写入到文件
-n 取消默认打印,常跟p配合达到只打印处理行的效果
-r 使用扩展正则表达式
**注意:i和n不要结合使用!会将文件内容进行清空**

2.2 条件-处理

2.2.1 条件:定位到行

/pattern/ 匹配pattern的行
/pattern1/,/pattern2/ 匹配pattern1到匹配pattern2的行
n 第n行
n,m第n到m行
$最后一行
! 取反,跟在定位条件后使用,如n!表示除了第n行
/pattern1/处理1;/pattern2/处理2 对匹配pattern1的行进行处理1,对匹配pattern2的进行处理2(不能在i和a动作中使用)
n处理1;m处理2 对第n行进行处理1,对第m进行处理2(不能在i和a动作中使用)

2.2.2 处理:

(1)p-print显示,!p取反显示

sed -n '/pattern/p' file               #显示匹配pattern内容所在的行
sed -n 'n,mp' file                     #显示n~m行
sed -n '/pattern1/,/pattern2/p' file   #显示含有pattern1到含有pattern2的行

(2)s-substitute替换(g-globle全局)(i-ignore case忽略大小写)
同VIM中的s///替换一样,也可以用&引用前面匹配的所有内容,用\1、\2...引用前面()内的内容

sed -i 's/pattern1/XXX/g' file          #将全文的pattern1替换为XXX,内容保存的文件中
sed -i 'n,ms/pattern1/XXX/g' file       #将n~m行的pattern1替换为XXX,内容保存的文件中

(3)s///gp替换显示

sed -n 's/pattern1/XXX/gp' file          #将全文的pattern1替换为XXX,内容打印在屏幕上
sed -n 'n,ms/pattern1/XXX/gp' file       #将n~m行的pattern1替换为XXX,内容打印在屏幕上

(4)i-insert在某行上面添加并显示内容

sed '1iabc,123,456' file                 #在第一行添加abc,123,456

(5)a-append在某行下面添加并显示内容

sed '$aabc,123,456' file                 #在最后一行添加abc,123,456

(6)d-delete删除特定行

sed -r '/^#/d' file                      #删除以#开头的行

(7)c-change改变特定行

sed '4cabc' file                         #将第4行改为abc

2.3 进阶用法

2.3.1 将匹配的内容写入文件

w动作,后面接空格+文件名

#将f1.txt的第二行,写入f2.txt中,取消默认打印
sed -n '2w f2.txt' f1.txt

2.3.2 操作匹配行的下一行

{n;action}动作

#匹配111的行,将下一行的2替换为b
sed '/111/{n;s/2/b/g}' f1.txt

2.4 sed暂存区

暂存空间相当于一个临时的仓库,在sed进行数据处理的时候,可以作为数据的暂存区域。暂存区域默认有一个换行符存在。


有4个动作可以利用暂存空间:
  1. h 把模式空间里的内容覆盖到暂存缓冲区
  2. H 把模式空间里的内容追加到暂存缓冲区
  3. g 把暂存缓冲区里的内容覆盖到模式空间,覆盖原有的内容
  4. G 把暂存缓冲区的内容追加到模式空间里,追加在原有内容的后面

用法例子:

#1 复制第一行,替换最后一行
sed '1h;$g' file
#2 复制第一行,追加到最后一行之后
sed '1h;$G' file
#3 删除第一行,用第一行替换最后一行
sed '1{h;d};$g' file
#4 用第一行替换文件的所有行
sed '1h;2,$g' file

3 awk

awk依次处理文件的每一行,并读取里面的每一个字段。

3.1 基本用法

# 格式
awk 参数 '模式-动作' 文件名

# 示例
awk '{print $0}' demo.txt

awk默认会根据空格和制表符,将每一行分成若干字段,依次用
$1$2$3代表第一个字段、第二个字段、第三个字段等等,
$0代表整行,
$NF代表最后一个字段,
$(NF-1)代表倒数第二个字段。

3.1.1 参数

-F指定分隔符,分隔符可以使用正则表示

#demo.txt
  root:x:0:0:root:/root:/usr/bin/zsh
  daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
  bin:x:2:2:bin:/bin:/usr/sbin/nologin

# 指定:为分隔符,打印第一段内容
$ awk -F ':' '{print $1}' demo.txt
root
daemon
bin

-v var=val设置变量

awk -v num=1000 '{print num}' f1.txt
1000

3.1.2 模式-动作

语法样式为:'匹配条件{动作}',不写动作默认是print

3.1.2.1 匹配条件

正则

/pattern/                    匹配pattern的行
/pattern1/,/pattern2/        从匹配pattern1到匹配pattern2的行
$n~/pattern/                 匹配第n个字段包含pattern的行
!/pattern/                   取反匹配pattern

比较

NR==n                        第n行
NR==n,NR==m                  第n到第m行
NR>2                         第3行往后

3.1.2.2 动作

语法:{ action1;action2 } 多个动作用;隔开

(1)print 显示

{print x,y,z}                      显示内容,x,y,z显示为x y z
{print x","y","z}                  显示内容,显示为x,y,z

print 支持显示变量,变量前不用加$
{print var}                        显示变量var的内容

print 显示字符串要加""否则会被当成变量
{print "var"}                      显示字符串var

print 支持函数
{print int(24.1234)}               int()是取整函数,显示24

(2)printf显示

printf ("格式化字符串",字符1,字符2)

常用字符类型
%s    字符类型
%d    十进制数字类型
%f    浮点数

修饰符
-    左对齐,默认是右对齐
#    修饰符,在8进制整数时在前面加个0,16进制整数时在前面加个0x

注意:printf输出后不会输出换行,需要在内容后面加\n

例子:
#aaa被打印成一个占15格、向左对齐的字符串
#88打印成一个占10格,向右对其的数字
#两个字符串用|分隔,结尾\n进行换行
awk 'BEGIN{printf "%-15s|%10d\n","aaa",88}'
aaa            |        88

(3)gsub 替换

语法:gsub(/要替换的信息/,"修改成什么信息",将哪列进行修改)

{gsub(/:/,"$",$NF)}                将最后一列的:替换为$
{gsub(/:/,"$",$NF);print $NF}      将最后一列的:替换为$,并打印

3.2 进阶用法

# 格式
awk 参数 'BEGIN{动作} 模式{动作} END{动作}' 文件名
BEGIN{}        在awk遍历文件前做的操作
END{}          在awk遍历文件后做的操作

# 示例1 在开头结尾打印提示
[root@node1 ~]$ awk 'BEGIN{print "操作开始"}{print $0}END{print "操作结束"}' f1.txt 
操作开始
aaa 222  333

333
操作结束

3.2.1 awk运算

  1. 赋值运算=
  2. 比较运算>、>=、==、<、<=、!=
  3. 数学运算+、-、*、/、%、^、++、--
  4. 逻辑运算&&、||
  5. 匹配运算~、!~

3.2.1.1 比较运算

比较运算,如果比较的是字符串,则按照ascii编码顺序表比较。如果结果为真用1表示,结果为假用0表示。
比较运算可以作为执行动作的前序条件。

#打印大于5的序列
seq 1 10 | awk '$1>5{print $1}'

3.2.1.2 数学运算

{print 1+1}                        显示2
{print 10*3}                       显示30
{print 10/3}                       显示3.33333,支持小数
{print 10^2}                       显示30

#求1~10的和及平均数
[root@node1 ~]$ seq 10 | awk '{sum=sum+$0;i++}END{print "sum="sum,"avg="sum/i}'
sum=55 avg=5.5

3.2.1.3 逻辑运算

#打印1到10序列,大于3且小于6的行
seq 1 10 | awk '$1>3&&$1<6{print $0}'

3.2.1.4 匹配运算

~模糊匹配,包含就可以
!~不匹配
==精确匹配
!=不等于

#打印/etc/passwd文件中,第1列含有ro的行
awk -F ":" '$1~"ro"{print $0}' /etc/passwd 
#结果
root:x:0:0:root:/root:/bin/bash
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin

3.2.2 awk特殊变量

变量 描述
FS 输入字段分隔符
OSF 输出字段分隔符
RS 输入记录(行)分隔符,默认是\n
ORS 输出记录(行)分隔符,默认是\n
#示例1:以:为分隔符,打印/etc/passwd的第1、2、3字段,输出的分隔符为+
awk 'BEGIN{FS=":";OFS="+"}NR==1{print $1,$2,$3}' /etc/passwd

#示例2:以:为分隔符,打印/etc/passwd的第1、2、3字段,输出的分隔符为+
awk 'BEGIN{FS=":";OFS="+"}NR==1{print $1,$2,$3}' /etc/passwd

#示例3:打印1+2+3+4+5+6+7+8+9+10+0,可用于求和
seq 1 10 | awk 'BEGIN{ORS="+"}{print $0}END{ORS="\n";print 0}'

#示例4:
[root@www ~]# cat contacts 
Riley Mullen
123 Main Street
Chicago,IL 60602
(312)555-1234

Riley Mullen
123 Main Street
Chicago,IL 60602
(312)555-1234

Riley Mullen
123 Main Street
Chicago,IL 60602
(312)555-1234
#期望输出
Riley Mullen (312)555-1234
Riley Mullen (312)555-1234
Riley Mullen (312)555-1234

#RS="",则每个记录是
Riley Mullen
123 Main Street
Chicago,IL 60602
(312)555-1234
#FS="\n",每个字段的分隔符是\n,共有4个字段

[root@www ~]# awk 'BEGIN{RS="";FS="\n"}{print $1,$4}' contacts 
Riley Mullen (312)555-1234
Riley Mullen (312)555-1234
Riley Mullen (312)555-1234

3.2.3 awk流程控制

3.2.3.1 if语句

多行写法:

#打印1到10,小于5原值打印,大于等于5除以2打印
seq 1 10 | awk '{
if ($1<5) 
print $1
else
print $1/2
}'

单行写法:

#打印1到10,小于5原值打印,大于等于5除以2打印
seq 1 10 | awk '{if ($1<5) print $1;else print $1/2}'
seq 1 10 | awk '{if ($1<5) {print $1}else {print $1/2}}'

3.2.3.2 for语句

多行写法:

1 2 3
4 5 6
7 8 9

#打印每行的和
seq 1 9 |xargs -n 3 | awk  '{                                         
sum=0
for(i=1;i<4;i++)
{sum=sum+$i}
print sum}'

单行写法:

1 2 3
4 5 6
7 8 9

#打印每行的和
seq 1 9 | xargs -n 3 | awk  '{sum=0;for(i=1;i<4;i++){sum+=$i}print sum}'
6
15
24

3.2.3.3 while语句

多行写法:

1 2 3
4 5 6
7 8 9

#打印每行的和
seq 1 9 |xargs -n 3 | awk  '{
sum=0
i=1
while (i<4)
{sum=sum+$i;i++}
print sum}'

单行写法:

1 2 3
4 5 6
7 8 9

#打印每行的和
seq 1 9 | xargs -n 3 | awk  '{sum=0;i=1;while(i<4){sum+=$i;i++}print sum}'
6
15
24

3.2.3.4 do while语句

与单纯的while语句类似

#打印每行的和
seq 1 9 | xargs -n 3 | awk '{sum=0;i=1;do{sum=sum+$i;i++}while(i<4);print sum}'
6
15
24

3.2.3.5 循环控制break

1 2 3
4 5 6
7 8 9

#打印每行的和,和大于8时退出循环
seq 1 9 | xargs -n 3 | awk  '{sum=0;i=1;while(i<4){sum+=$i;if(sum>8){break}i++};print sum}'

3.2.4 awk小技巧

打印test文本的行数

awk 'END{print NR}' test

打印test文本最后一行的内容

awk 'END{print $0}' test

打印test文本的列数

awk 'END{print NF}' test

3.2.5 awk数组

3.2.5.1 建立数组

# 数组名array,下标index以及相应的值value。
array[index] = value  

3.2.5.2 读取数组内容

# 输出的顺序是随机的
{ for (item in array)  print array[item]}
# Len 是数组的长度
{len=length(array);for(i=1;i<=len;i++)  print array[i]}

相关文章

网友评论

      本文标题:7、文本处理三剑客

      本文链接:https://www.haomeiwen.com/subject/rsmtbktx.html