Linux文本处理三剑客awk、sed、grep入门

Linux文本处理三剑客awk、sed、grep入门

 

目录

1.AWK命令简介

2.sed命令简介

3.grep命令简介


1.AWK命令简介

AWK是一门解释型的编程语言,它的名字来源于它的三位作者的姓氏:Alfred Aho,Peter Weinberger和Brian Kernighan。AWK能够应用于广泛的计算和数据处理任务。所有的GNU/Linux发行版都自带GAWK,即GNU AWK,是AWK的扩展并且与AWK完全兼容。Awk也是一种模式匹配语言。它通过正则表达式匹配数据,然后就可以对这些匹配的数据进行相应的操作了。

一、基本格式:

AWK命令两种格式:

第一种格式,awk从input-file中获取输入流,然后执行单引号内的程序。

awk [options] 'program' input-file

例1:awk ‘{print $2, $4}’ myfile  #输出每一行的第二个和第四个单词

例2:awk ‘length<60 {print}’ myfile #将长度小于60个字符的所有行全部输出

第二种格式则是从文件program-file中获取将要执行的程序。

awk -f program-file input-file  # –f 选项,表示执行文件中的命令

program-file的内容:

#!/usr/bin/awk –f

BEGIN{print "Output start!"};
{print};
END{print "Output done!"};

以上两种格式可以统一表示为:

awk [ -F re] [parameter...] ['prog'] [-f progfile] in_file

参数说明:

-F re:    允许awk更改其字段分隔符(默认为空格,可以设置为其他,如冒号)。

Parameter:该参数帮助为不同的变量赋值。

'prog':    awk的程序语句段,这个语句段必须用单括号,以防被shell解释。这个程序语句段的标准形式为:

'pattern {action}'

其中pattern参数可以是egrep正则表达式中的任何一个。action参数总是被大括号包围,它由一系列awk语句组成,可以省略pattern和 action之一,但不能两者同时省略,当省略pattern时没有样式匹配,表示对所有行(记录)均执行操作,省略action时执行缺省的操作——在标准输出上显示。其中例2中的“length<60”就是pattern,其中 pattern 表示 AWK 在数据中查找的内容,理解为条件。print就是action,而 action 是在找到匹配内容时所执行的一系列。命令意思就是满足什么条件(pattern)执行什么动作(action)。

AWK 包含两种特殊的模式:BEGIN 和 END。BEGIN 模式指定了处理文本之前需要执行的操作,END 模式指定了处理完所有行之后所需要执行的操作。

-f progfile:允许awk调用并执行progfile指定有程序文件。progfile是一个文本文件,他必须符合awk的语法。

in_file:awk的输入文件,awk允许对多个输入文件进行处理。值得注意的是awk不修改输入文件。如果未指定输入文件,awk将接受标准输入,并将结果显示在标准输出上。awk支持输入输出重定向。

 

二、内置变量:

  • awk中定义了很多内置变量,这些内置的变量可以在awk程序中引用或修改。
  • FNR:当前处理的记录号。
  • FS :字段的分隔符,默认为空格。
  • IGNORECASE:如果该变量设置为非0值,在进行字符串匹配时忽略大小写。
  • NF:当前记录中的字段个数。
  • NR:已经读出的记录数。
  • OFMT:数字的输出格式。
  • OFS:  输出的字段分隔符,默认为空格。
  • ORS:  输出的记录分隔符,默认为新行。
  • RS:   输入记录的分隔符,默认为新行。

等等

例3:

显示文本文件myfile中第七行到第十五行中以字符%分隔的第一字段,第三字段和第七字段:

awk -F % 'NR>=7,NR<=15 {print $1 $3 $7}' myfile

 

三、内置函数

awk定义并支持了一系列的内置函数,使得awk提供的功能更为完善和强大,例如,awk使用了一系列的字符串处理内置函数。

gsub(r,s) : 在整个$0中用s代替r

gsub(r,s,t) :在整个t中用s替代r

index(s,t) :返回s中字符串t的第一位置

length(s) : 返回s长度

match(s,r) :测试s是否包含匹配r的字符串

split(s,a,fs) :在fs上将s分成序列a

sprint(fmt,exp) :返回经fmt格式化后的exp

sub(r,s) :用$0中最左边最长的子串代替s

substr(s,p) :返回字符串s中从p开始的后缀部分

substr(s,p,n) :返回字符串s中从p开始长度为n的后缀部分

 

例4:

该命令行将显示文本myfile中所有超过80个字符的行号,在这里,用0表示整个记录(行)。

awk 'length($0)>80 {print NR}' myfile

 

2.sed命令简介

sed命令是一个面向字符流的非交互式编辑器,也就是说sed不允许用户与它进行交互操作。sed是按行来处理文本内容的。在shell中,使用sed来批量修改文本内容是非常方便的。

sed的命令格式:

sed [option] command file

1.[option]:

  • -n :使用安静(silent)模式。在一般 sed 的用法中,所有来自stdin的数据一般都会被列出到终端上。加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
  • -e :直接在命令列模式上进行 sed 的动作编辑;
  • -f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
  • -r :sed 的动作支持的是延伸型正规表示法的语法。(默认是基础正规表示法语法)
  • -i :直接修改读取的文件内容,而不是输出到终端。

2.Command:

  • a :新增行, a 的后面可以是字串,而这些字串会在新的一行出现(目前的下一行);
  • c :取代行, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行;
  • d :删除行,因为是删除,所以 d 后面通常不接任何参数,直接删除地址表示的行;
  • i :插入行, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
  • p :列印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行;
  • s :替换,可以直接进行替换的工作,通常这个 s 的动作可以搭配正规表示法。

4.范例:

myfile.txt内容:

abcdefg

hijklmn

opqrst

uvwxyz

 

范例1:sed ‘1,3d’ myfile.txt  #删除第一行到第三行的内容

输出:uvwxyz

其中1,3d中的d表示删除,而d前面的表示删除的行的地址,而1,3表示一个地址范围,也就是删除第1行和第2行。地址范围的表示一般是  m,n 表示对m和n行之间的所有行进行操作。sed的地址寻址中可以使用$表示最后一行,例如 m,$ 表示对m行以及其后面的所有行进行操作。m,$d就是删除m行以及其后面的所有行内容。当然我们还可以对某一行进行操作,例如2d表示仅仅删除第2行。除了使用数字范围 m,n 表示多行区间,以及m表示单行以外,我们还可以使用正则表达式选出符合条件的行,并对这些行进行操作。

注:这只影响到输出流,myfile.txt的第一行到第三行并没有被删除。

范例2:sed  -i ‘1,3d’ myfile.txt  #直接删除第一行到第三行的内容, 不输出到终端

 

范例3:sed '1a Hello World!' myfile.txt  #添加行

a命令表示在指定行的后面附加一行,1a则是在第一行的后面添加一行,添加的内容就是a后面的内容,如果a的前面没有地址限定则在所有行的后面都会添加指定的字符串。

 

范例4:sed '1c Hello World' myfile.txt  #替换行

 

命令c会替换指定的行的所有内容,替换成其后面的字符串,所有的新增,删除,替换行,这些命令前面的地址修饰都可以指定地址空间,也都可以使用正则表达式,命令会应用在选出的符合地址条件的所有行上面,例如:

范例5:sed '/^h/c Hello World!' myfile.txt  #替换以h开头的行,其内容是c命令后面的字符串

abcdefg

Hello world!

opqrst

uvwxyz

范例6:sed 's/abc/ABC/'myfile.txt  #部分字符串而不是整行

执行的结果是我们文件中的 abc 被替换成 ABC ,命令其含义:s/待替换的字符串/新字符串/ 也就是说使用后面的 AA 替换文件中出现的前面的 aa。实际上这里的替换仅仅替换每一行遇到的第一个aa,我们修改一下文件的内容:

 

范例7:sed 's/aa/AA/g' myfile.txt #替换字符串

最后一个斜杠后面g选项,表示进行全局替换,也就是说所有符合条件的旧字符串都会被替换成新字符串。s命令也可以进行地址选择,也就是在s的前面加上地址空间限定。

 

3.grep命令简介

grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。在某个目录下的文本文件中查找一个字符串,可以使用‘grep’命令;‘grep’在几个文本中搜索指定的字符串。

 

例如正在‘/user/code’目录下搜索带字符串‘stdio’的文件:

例1:grep stdio [./]usr/code/*

 

默认情况下,‘grep’只搜索当前目录。明确要求搜索子目录:grep –r

例2:grep –r stdio [./]usr/code/*
忽略子目录:grep -d skip

例3:grep –d skip stdio [./]usr/code/* (与grep stdio [./]usr/code/*效果一样)

注:搜索当前目录与子目录:grep –r stdio *

当然,如果预料到有许多输出,您可以将其转到‘less’上阅读:

3. 特殊的–在多个文件中进行查询
例4:grep “stdio”  *.c   ( #在当前目录下所有.c文件中查找字符串”stdio”)
 

例5:grep –r stdio [./]usr/code/* | less

less是用来分页显示内容的一个 命令,其最基本的用法为:

less filename,例如: less text.txt

less的翻页,查找操作:

q:退出;空格:下一页;b:上一页;g:到第一行;G:到结尾。

‘*’ 表示搜索全部文件,如果不全部搜索的话,必需提供一个文件过滤方式。

grep –i string 文件所在目录/*:不区分大小写地搜索。默认情况区分大小写,

grep -l string 文件所在目录/*:只列出匹配的文件名,

grep –L string 文件所在目录/*:列出不匹配的文件名,

grep –w string 文件所在目录/*:只匹配整个单词,而不是字符串的一部分

grep -C number:匹配的上下文分别显示[number]行,

这里还有些用于搜索的特殊符号:

\< 和 \> 分别标注单词的开始与结尾。

例如:

grep man * 会匹配 ‘Batman’、‘manic’、‘man’等,

grep '\

grep '\' 只匹配‘man’,而不是‘Batman’或‘manic’等其他的字符串。

你可能感兴趣的:(Linux)