sed:流编辑器、操作模式如下
1、一次从输入中读取一行数据
2、根据所提供的编辑器命令行匹配数据
3、按照命令修改流中的数据
4、将新的数据输出到stdout
[root@localhost ~]# echo "This is a test" | sed 's/test/big test/' This is a big test
实例中sed 编辑器使用了s命令,s命令会用斜线间指定的第二个文本字符串来替换第一个文本字符串
示例:
[root@localhost ~]# cat data1.txt The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog. [root@localhost ~]# sed 's/dog/cat/' data1.txt The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat. The quick brown fox jumps over the lazy cat.
[root@localhost ~]# sed -e 's/brown/green/;s/dog/cat/' data1.txt The quick green fox jumps over the lazy cat. The quick green fox jumps over the lazy cat. The quick green fox jumps over the lazy cat. The quick green fox jumps over the lazy cat.
[root@localhost ~]# sed -e ' > s/brown/green/ > s/fox/elephant/ > s/dog/cat/' data1.txt The quick green elephant jumps over the lazy cat. The quick green elephant jumps over the lazy cat. The quick green elephant jumps over the lazy cat. The quick green elephant jumps over the lazy cat.
[root@localhost ~]# cat script1.sed s/brown/green/ s/fox/elephant/ s/dog/cat/ [root@localhost ~]# sed -f script1.sed data1.txt The quick green elephant jumps over the lazy cat. The quick green elephant jumps over the lazy cat. The quick green elephant jumps over the lazy cat. The quick green elephant jumps over the lazy cat.
[root@localhost ~]# cat data4.txt This is a test of the test script. This is the second test of the test script. [root@localhost ~]# sed 's/test/trial/' data4.txt This is a trial of the test script. This is the second trial of the test script.
[root@localhost ~]# sed 's/test/trial/g' data4.txt This is a trial of the test script. This is the second trial of the test script.
此处为全局替换
[root@localhost ~]# sed 's/test/trial/2' data4.txt
This is a test of the trial script.
This is the second test of the trial script.
此处匹配的格式为每行匹配的第二个格
[root@localhost ~]# cat data5.txt This is a test line. This is a different line. [root@localhost ~]# sed -n 's/test/trial/p' data5.txt This is a trial line.
只会打印替换的
[root@localhost ~]# sed 's/test/trial/w test.txt' data5.txt This is a trial line. This is a different line.
会将替换过的行输出到test.txt文件
替换字符
[root@localhost ~]# sed 's/\/bin\/bash/\/bin\/csh/' /etc/passwd
[root@localhost ~]# sed 's#/bin/bash#/bin/csh#' /etc/passwd
使用地址
[root@localhost ~]# sed '2s/fox/kkkkkkk/' data1.txt The quick brown fox jumps over the lazy dog. The quick brown kkkkkkk jumps over the lazy dog. The quick brown fox jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
[root@localhost ~]# sed '2,3s/fox/jjjjj/' data1.txt The quick brown fox jumps over the lazy dog. The quick brown jjjjj jumps over the lazy dog. The quick brown jjjjj jumps over the lazy dog. The quick brown fox jumps over the lazy dog.
[root@localhost ~]# sed '2,$s/fox/lllll/' data1.txt The quick brown fox jumps over the lazy dog. The quick brown lllll jumps over the lazy dog. The quick brown lllll jumps over the lazy dog. The quick brown lllll jumps over the lazy dog.
2、使用文本模式过滤器
[root@localhost tmp]# sed -n '/nobody/s/18353/00000/p' passwd nobody:*:00000:0:99999:7:::
3、命令组合
[root@localhost ~]# sed '2{
> s/brown/green/
> s/dog/cat/
> }' data1.txt
The quick brown fox jumps over the lazy dog.
The quick green fox jumps over the lazy cat.
The quick brown fox jumps over the lazy dog.
The quick brown fox jumps over the lazy dog.
两条命令都会作用到该地址上,也可以在一组命令前指定一个地址区间
[root@localhost ~]# sed '2,${
> s/brown/green/
> s/dog/cat/
> }' data1.txt
The quick brown fox jumps over the lazy dog.
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
The quick green fox jumps over the lazy cat.
4、删除行
[root@localhost ~]# sed 'd' data1.txt
通过行号指定
[root@localhost ~]# cat data6.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
[root@localhost ~]# sed '3d' data6.txt This is line number 1. This is line number 2. This is line number 4.
[root@localhost ~]# sed '2,3d' data6.txt This is line number 1. This is line number 4.
[root@localhost ~]# sed '3,$d' data6.txt This is line number 1. This is line number 2.
[root@localhost ~]# sed '/number 1/d' data6.txt This is line number 2. This is line number 3. This is line number 4.
5、插入和附加文本
[root@localhost ~]# echo '123456' | sed 'i 234567' 234567 123456
[root@localhost ~]# echo '123456' | sed 'a 234567'
123456
234567
[root@localhost ~]# sed '3i jkjjkjkjkj' data6.txt This is line number 1. This is line number 2. jkjjkjkjkj This is line number 3. This is line number 4.
将一个新行插入到数据流第三行后
[root@localhost ~]# sed '3a jkjjkjkjkj' data6.txt This is line number 1. This is line number 2. This is line number 3. jkjjkjkjkj This is line number 4.
[root@localhost ~]# sed '$i jkjfkfs' data6.txt This is line number 1. This is line number 2. This is line number 3. jkjfkfs This is line number 4.
6、修改行
[root@localhost ~]# sed '3c fjsfjsdfsjdfhshf' data6.txt This is line number 1. This is line number 2. fjsfjsdfsjdfhshf This is line number 4.
[root@localhost ~]# sed '/number 3/c hfjshfjshfjksdfs' data6.txt This is line number 1. This is line number 2. hfjshfjshfjksdfs This is line number 4.
[root@localhost ~]# sed '2,3c fsdfsd' data6.txt This is line number 1. fsdfsd This is line number 4.
7、转换命令
[root@localhost ~]# sed 'y/1234/5678/' data6.txt This is line number 5. This is line number 6. This is line number 7. This is line number 8.
grep 选项
-c 只输出匹配行的计数
-i 不区分大小写
在当前目录下文件中查找sort关键字
grep "sort" *
在当前目录下的以*.txt 结尾的文件中查找sort关键字 grep "sort" *.txt
行匹配
[root@localhost ~]# grep -c "root" /etc/passwd 2
返回数字2 包含root关键字的行数有两行
行数
[root@localhost ~]# grep -n "dog" data1.txt 1:The quick brown fox jumps over the lazy dog. 2:The quick brown fox jumps over the lazy dog. 3:The quick brown fox jumps over the lazy dog. 4:The quick brown fox jumps over the lazy dog.
行数输出在第一列,后跟包含48的每一匹行
显示非匹配行
grep -v "48" data.txt
精确匹配
grep "dog\>" data1.txt
grep -w "dog" data1.tx
awk的基本格式为:
awk [选项] '脚本命令' 文件名
| 选项 | 含义 |
| -F fs | 指定以fs作为输入行的分隔符,awk命令默认分隔符为空格或制表符 |
| -f file | 从脚本文件中读取awk脚本指令,以取代直接在命令行中输入指令 |
| -v var=val | 在执行处理过程之前,设一个变量var,并给其设备初始值为val |
awk由两部分组成,分别为匹配规则和执行命令
'匹配规则{执行命令}'
匹配规则,和 sed 命令中的 address 部分作用相同,用来指定脚本命令可以作用到文本内容中的具体行,可以使用字符串(比如 /demo/,表示查看含有 demo 字符串的行)或者正则表达式指定,整个脚本命令是用单引号‘’括起,而其中的执行命令部分需要用大括号{}括起来
awk执行程序时,如果没有执行指定命令,则默认会把匹配的行输出;如果不指定匹配规则,则默认匹配文本中所有的行
示例:
[root@localhost ~]# awk '/^$/{print '123'}' /etc/httpd/conf/httpd.conf
如果有多少空格,就会打印多少123
awk使用数字字段变量
$0 代表整个文本行
$1 代表文本行中的第一个数据字段
$2 代表文本行中的第二个数据字段
$n 代表文本行中的第n个数据字段
[root@localhost ~]# cat data1.txt
The quick brown fox jumps over the lazy dogfsf.
The quick brown fox jumps over the lazy dogfs.
The quick brown fox jumps over the lazy dogffsfs.
The quick brown fox jumps over the lazy dog.
[root@localhost ~]# awk '{print $3}' data1.txt
brown
brown
brown
brown
$3 代表该文本的第3个字段,如果是其他分隔符的文本 可以通过-F 指定
awk 脚本命令使用多个命令awk允许许多条命令组合成一个正常的程序。要在命令行上的程序脚本中使用多条命令,只要在命令之间放个;即可
[root@localhost ~]# echo 'My name is Rich' | awk '{$2="age";print $0}'
My age is Rich
第一条命令会给字段变量$2赋值。第二条命令会打印整个数据段
除此之外,也可以一行一行的输入程序脚本命令
[root@localhost ~]# echo 'My name is Rich' | awk '{
> $2="age"
> print $0}'
My age is Rich
使用了起始单引号后,bash shell会使用>来提示输入更多数据,可以每次在每行加一条命令,直到输入了结尾的单引号
awk从文件中读取程序awk 允许将脚本命令存储到文件中,然后再在命令行中引用
[root@localhost ~]# cat awk.sh
{print $1 "'s home directory is " $6}
[root@localhost ~]# awk -F: -f awk.sh /etc/passwd
脚本文件会使用print命令打印/etc/passwd 文件的主目录数据字段(字段变量 $6),以及 userid 数据字段(字段变量 $1)。
注意,在程序文件中,也可以指定多条命令,只要一条命令放一行即可,之间不需要用分号。
awk BEGIN关键字[root@localhost ~]# awk 'BEGIN{print "this is data66.txt"}{print $0}' data6.txt
this is data66.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
BEGIN部分的脚本指令会在awk命令处理数据前运行,而真正用来处理数据的是第二段脚本命令
awk END关键字和关键字BEGIN相对应,END关键字允许我们指定一些脚本命令,awk会在读完数据后执行
awk 'BEGIN{print "start"}/This is line number 1/{print $0}END{print "stop"}' data6.txt
awk使用变量
在awk的脚本程序中,支持使用变量来存取值,awk支持两种不同类型的变量
内建变量:awk本身就创建好,用户可以直接拿来用的变量,这些变量用来存放处理数据文件中的某些字段和记录的信息
自定义变量:awk支持用户自定义变量
内建变量
awk程序使用内建变量来引用程序数据里的一些特殊功能。常见一些内建变量包括($0 $1 $2..$n)以及一下的这些变量
| 变量 | 功能 |
| FIELDWIDTHS | 有空格分隔的一列数字,定义了每个数据字段的确切宽度 |
| FNR | 当前输入文档的记录编号,常在有多个文件时使用 |
| NR | 输入流的当前记录编号 |
| FS | 输入字段分隔符 |
| RS | 输入记录分隔符,默认为换行符\n |
| OFS | 输出字段分隔符,默认为空格 |
| ORS | 输出记录分隔符,默认为换行符\n |
[root@localhost ~]# awk 'BEGIN{OFS="-"}{print $1,$2,$3,$4,$5 }' data6.txt
This-is-line-number-1.
This-is-line-number-2.
This-is-line-number-3.
This-is-line-number-4.
print 会自动将OFS变量的数值放在输出的每个字段间,通过设置OFS变量,可以在输出中使用任意字符串来分隔字段
FILEDWIDTHS变量允许用户不依靠字段分隔符来读取记录,在一些应用程序中,数据并没有使用字段分隔符,而是被放置在了记录中的特定列,这种情况下,必须设定 FIELDWIDTHS 变量来匹配数据在记录中的位置。
[root@localhost ~]# awk 'BEGIN{FIELDWIDTHS="3 5 2 5"}{print $1,$2,$3,$4}' data1b
100 5.324 75 96.37
115 -2.34 91 94.00
058 10.12 98 100.1
[root@localhost ~]# awk 'BEGIN{FS="\n";RS=""}{print $1,$2}' data2
Riley Mullen 123 Main Street
Frank Williams 456 Oak Street
Haley Snell 4231 Elm Street
环境变量信息
| 变量名 | 功能 |
| ARGC | 命令行参数个数 |
| ARGIND | 当前文件在ARGC中的位置 |
| ARGV | 包含命令行参数的数据 |
| CONVFMT | 数字的转换格式%.6g |
| ERRNO | 读取或关闭输入文件发生错误时的系统错误号 |
| ENVIRON | 当前 shell 环境变量及其值组成的关联数组。 |
| FFILENAME | 当前输入文档的名称 |
| FNR | 当前数据文件中的住宿据行数 |
| IGNORECASE | 设置成非0值时,忽略awk命令中出现的字符串的字符大小写 |
| NF | 数据文件中的字段总数 |
| NR | 已处理的输入记录数 |
| OFMT | 数字的输出格式,默认值为 %.6g。 |
| OFMT | 由 match 函数所匹配的子字符串的长度。 |
| TSTART | 由 match 函数所匹配的子字符串的起始位置。 |
自定义变量
awk允许用户定义自己的变量在脚本程序中使用,awk自定义变量名可以是任意数目的字母,数字和下划线,但不能以数字开头,awk变量名区分大小写
[root@localhost ~]# awk '
> BEGIN{
> test="this is test"
> print test
> test=45
> print test
> }'
this is test
45
[root@localhost ~]# awk 'BEGIN{test="this is test";print test;test=45;print test}'
this is test
45
print语句输出的时test变量的当前值
也可以用awk命令行来给程序中的变量赋值,这允许在这正常的代码之外赋值,随时改变变量的值
[root@localhost ~]# awk -v n=2 -F, '{print $n }' data1
data12
data22
data32
可以使用-v 命令行参数,它可以实现在BEGIN代码之前设定变量,在命令行参数必须放在脚本代码之前
awk使用数组
awk使用关联数组提供数组共功能
关联数组与数字数组不同之处在于,他的索引值可以是任意文本字符串,用户不需要用连续的数字来标识数组中放的数据元素;相反、关联数组用各种字符串来引用值。每个索引字符串都必须能够唯一地标识出赋给它的数据元素
关联数组的定义和使用
var[index]=element
其中 var是数组名,index是关联数组的索引值,element是数据元素值
[root@localhost ~]# capital['1']='1' [root@localhost ~]# capital['2']='2' [root@localhost ~]# capital['3']='3'
在引用数组变量时,必须用索引值(index)来提取相应的数据元素值
[root@localhost ~]# awk 'BEGIN{capital["1"]=1;print capital["1"]}'
1
数组变量也是变量,也可以使用其进行基本的算术运算
[root@localhost ~]# awk 'BEGIN{
> var[1]=1
> var[2]=2
> print var[1]+var[2]
> }'
3
关联数组的遍历
在awk中遍历关联数组,也可以用for语句的一种特殊形式:
fot (var in array)
{
statents
}
这个for循环语句会在每次循环时将关联数组array的下一个索引值赋给变量var,然后执行一遍statements
注:在整个遍历中,传给var的都是每个元素的索引值(也就是index),不是数组元素的值
[root@localhost ~]# awk 'BEGIN{
> var[1]=1
> var[2]=2
> var[3]=3
> for (test in var){
> print test"---->"var[test]
> }
> }'
1---->1
2---->2
3---->3
注:索引值不会按任何特定顺序返回,但他们都能够指向对应的数据元素值
删除数组变量
awk程序还支持从关联数组中删除某个数组索引,使用delete命令就可以,此命令会从数组中删除指定的索引值及相关的数据元素值
delete命令的基本格式如下:
delete array[index]
[root@localhost ~]# awk 'BEGIN{
var[1]=1
var[2]=3
> var[3]=2
> for(i in var){
> print i"---->"var[i]
> }
> print "--------"
> delete var[2]
> }'
1---->1
2---->3
3---->2
--------
一旦从关联数组中删除了索引值,就没法再用它来提取元素值
awk使用分支结构
awk支持标准的if-then-else格式的if语句,其基本格式为:
if(condition)
statement1
else
statements
也可以将它放在一行上
if(condition) statement1;else statement
awk '{if($1>20) print $1*2;else print $1/2}' data4
awk使用循环结构
awk脚本程序中,可以使用while、do-while、for这3种循环结构,他们各自的基本格式如下
| 基本格式 | 实例 |
|
while(条件){ 运行代码; } |
[root@localhost ~]# cat data5 [root@localhost ~]# awk '{ |
|
do{ 运行代码; }while(条件) |
[root@localhost ~]# awk '{ > total=0 > i=1 > do > { > total +=$i > i++ > }while(total < 150) > print total }' data5 250 160 315 |
|
for(变量;条件;计数器){ 运行代码 } |
[root@localhost ~]# awk '{ > total=0 > for(i=1;i<4;i++){ > total+=$i > } > avg=total/3 > print "average:",avg > }' data5 average: 128.333 average: 137.667 average: 176.667 |
















