sed、awk工具

ed

sed意为流编辑器(Stream Editor),在Shell脚本和Makefile中作为过滤器使用非常普遍,也就是把前一个程序的输出引入sed的输入,经过一系列编辑命令转换为另一种格式输出。sed和vi都源于早期UNIX的ed工具,所以很多sed命令和vi的末行命令是相同的。

sed命令行的基本格式为

sed option 'script' file1 file2 ...

sed option -f scriptfile file1 file2 ...

选项含义:

--version              显示sed版本。

--help                 显示帮助文档。

-n,--quiet,--silent    静默输出,默认情况下,sed程序在所有的脚本指令执行完毕后,将自动打印模式空间中的内容,这些选项可以屏蔽自动打印。

-e script              允许多个脚本指令被执行。

-f script-file,

--file=script-file     从文件中读取脚本指令,对编写自动脚本程序来说很棒!

-i,--in-place          直接修改源文件,经过脚本指令处理后的内容将被输出至源文件(源文件被修改)慎用!

-l N, --line-length=N 该选项指定l指令可以输出的行长度,l指令用于输出非打印字符。

--posix                禁用GNU sed扩展功能。

-r, --regexp-extended 在脚本指令中使用扩展正则表达式

-s, --separate         默认情况下,sed将把命令行指定的多个文件名作为一个长的连续的输入流。而GNU sed则允许把他们当作单独的文件,这样如正则表达式则不进行跨文件匹配。

-u, --unbuffered       最低限度的缓存输入与输出。

以上仅是sed程序本身的选项功能说明,至于具体的脚本指令(即对文件内容做的操作)后面我们会详细描述,这里就简单介绍几个脚本指令操作作为sed程序的例子。

a,  append          追加

i,  insert          插入

d,  delete          删除

s,  substitution    替换

如:$ sed "2a itcast" ./testfile 在输出testfile内容的第二行后添加"itcast"。

$ sed "2,5d" testfile

sed处理的文件既可以由标准输入重定向得到,也可以当命令行参数传入,命令行参数可以一次传入多个文件,sed会依次处理。sed的编辑命令可以直接当命令行参数传入,也可以写成一个脚本文件然后用-f参数指定,编辑命令的格式为:

/pattern/action

其中pattern是正则表达式,action是编辑操作。sed程序一行一行读出待处理文件,如果某一行与pattern匹配,则执行相应的action,如果一条命令没有pattern而只有action,这个action将作用于待处理文件的每一行。

常用sed命令

/pattern/p 打印匹配pattern的行

/pattern/d 删除匹配pattern的行

/pattern/s/pattern1/pattern2/ 查找符合pattern的行,将该行第一个匹配pattern1的字符串替换为pattern2

/pattern/s/pattern1/pattern2/g 查找符合pattern的行,将该行所有匹配pattern1的字符串替换为pattern2

使用p命令需要注意,sed是把待处理文件的内容连同处理结果一起输出到标准输出的,因此p命令表示除了把文件内容打印出来之外还额外打印一遍匹配pattern的行。比如一个文件testfile的内容是

123

abc

456

打印其中包含abc的行

$ sed '/abc/p' testfile

123

abc

abc

456

要想只输出处理结果,应加上-n选项,这种用法相当于grep命令

$ sed -n '/abc/p' testfile

abc

使用d命令就不需要-n参数了,比如删除含有abc的行

$ sed '/abc/d' testfile

123

456

注意,sed命令不会修改原文件,删除命令只表示某些行不打印输出,而不是从原文件中删去。

使用查找替换命令时,可以把匹配pattern1的字符串复制到pattern2中,比如:

$ sed 's/bc/-&-/' testfile

123

a-bc-

456

pattern2中的&表示原文件的当前行中与pattern1相匹配的字符串

再比如:

$ sed 's/\([0-9]\)\([0-9]\)/-\1-~\2~/' testfile

-1-~2~3

abc

-4-~5~6

pattern2中的\1表示与pattern1的第一个()括号相匹配的内容,\2表示与pattern1的第二个()括号相匹配的内容。sed默认使用Basic正则表达式规范,如果指定了-r选项则使用Extended规范,那么()括号就不必转义了。如:

sed -r 's/([0-9])([0-9])/-\1-~\2~/' out.sh

替换结束后,所有行,含有连续数字的第一个数字前后都添加了“-”号;第二个数字前后都添加了“~”号。

可以一次指定多条不同的替换命令,用“;”隔开:

$ sed 's/yes/no/;s/static/dhcp/' ./testfile

注:使用分号隔开指令。

也可以使用 -e 参数来指定不同的替换命令,有几个替换命令需添加几个 -e 参数:

$ sed -e 's/yes/no/' -e 's/static/dhcp/' testfile

注:使用-e选项。

如果testfile的内容是

<html><head><title>Hello World</title></head>

<body>Welcome to the world of regexp!</body></html>

现在要去掉所有的HTML标签,使输出结果为:

Hello World

Welcome to the world of regexp!

怎么做呢?如果用下面的命令

$ sed 's/<.*>//g' testfile

结果是两个空行,把所有字符都过滤掉了。这是因为,正则表达式中的数量限定符会匹配尽可能长的字符串,这称为贪心的(Greedy)。比如sed在处理第一行时,<.*>匹配的并不是<html>或<head>这样的标签,而是

<html><head><title>Hello World</title>

这样一整行,因为这一行开头是<,中间是若干个任意字符,末尾是>。那么这条命令怎么改才对呢?留给同学们思考练习。

awk

sed以行为单位处理文件,awk比sed强的地方在于不仅能以行为单位还能以列为单位处理文件。awk缺省的行分隔符是换行,缺省的列分隔符是连续的空格和Tab,但是行分隔符和列分隔符都可以自定义,比如/etc/passwd文件的每一行有若干个字段,字段之间以:分隔,就可以重新定义awk的列分隔符为:并以列为单位处理这个文件。awk实际上是一门很复杂的脚本语言,还有像C语言一样的分支和循环结构,但是基本用法和sed类似,awk命令行的基本形式为:

awk option 'script' file1 file2 ...

awk option -f scriptfile file1 file2 ...

和sed一样,awk处理的文件既可以由标准输入重定向得到,也可以当命令行参数传入,编辑命令可以直接当命令行参数传入,也可以用-f参数指定一个脚本文件,编辑命令的格式为:

/pattern/{actions}

condition{actions}

和sed类似,pattern是正则表达式,actions是一系列操作。awk程序一行一行读出待处理文件,如果某一行与pattern匹配,或者满足condition条件,则执行相应的actions,如果一条awk命令只有actions部分,则actions作用于待处理文件的每一行。比如文件testfile的内容表示某商店的库存量:

ProductA 30

ProductB 76

ProductC 55

打印每一行的第二列:

$ awk '{print $2;}' testfile

30

76

55

自动变量$1、$2分别表示第一列、第二列等,类似于Shell脚本的位置参数,而$0表示整个当前行。再比如,如果某种产品的库存量低于75则在行末标注需要订货:

$ awk '$2<75 {printf "%s\t%s\n", $0, "REORDER";} $2>=75 {print $0;}' testfile

ProductA 30 REORDER

ProductB 76

ProductC 55 REORDER

可见awk也有和C语言非常相似的printf函数。awk命令的condition部分还可以是两个特殊的condition-BEGIN和END,对于每个待处理文件,BEGIN后面的actions在处理整个文件之前执行一次,END后面的actions在整个文件处理完之后执行一次。

awk命令可以像C语言一样使用变量(但不需要定义变量),比如统计一个文件中的空行数

$ awk '/^ *$/ {x=x+1;} END {print x;}' testfile

就像Shell的环境变量一样,有些awk变量是预定义的有特殊含义的:

awk常用的内建变量

FILENAME    当前输入文件的文件名,该变量是只读的

NR          当前行的行号,该变量是只读的,R代表record

NF          当前行所拥有的列数,该变量是只读的,F代表field

OFS         输出格式的列分隔符,缺省是空格

FS          输入文件的列分融符,缺省是连续的空格和Tab

ORS         输出格式的行分隔符,缺省是换行符

RS          输入文件的行分隔符,缺省是换行符

例如打印系统中的用户帐号列表

$ awk 'BEGIN {FS=":"} {print $1;}' /etc/passwd

awk也可以像C语言一样使用if/else、while、for控制结构。可自行扩展学习。

 

转载于:https://www.cnblogs.com/wanghao-boke/p/11488553.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/384834.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言正则表达式

POSIX规定了正则表达式的C语言库函数&#xff0c;详见regex(3)。我们已经学习了很多C语言库函数的用法&#xff0c;读者应该具备自己看懂man手册的能力了。本章介绍了正则表达式在grep、sed、awk中的用法&#xff0c;学习要能够举一反三&#xff0c;请读者根据regex(3)自己总结…

makefile通用版本

实际当中程序文件比较大&#xff0c;这时候对文件进行分类&#xff0c;分为头文件、源文件、目标文件、可执行文件。也就是说通常将文件按照文件类型放在不同的目录当中&#xff0c;这个时候的Makefile需要统一管理这些文件&#xff0c;将生产的目标文件放在目标目录下&#xf…

Python3OS文件/方法

Python3OS文件/方法 os模块提供了非常丰富的方法用来处理文件和目录。 方法 描述 os.access(path,mode) 检验权限模式 os.chdir(path) 改变当前工作目录 os.chflags(path,flags) 设置路径的标记为数字标记 os.chmod(path,mode) 更改权限 os.chown(path,uid,gid) 更改…

Python3文件

open()方法 Python open()方法永于打开一个文件&#xff0c;并返回文件对象&#xff0c;并对文件进行处理过程中都需要用到这个方法&#xff0c;如果该文件无法被打开&#xff0c;则抛出OSError 注意&#xff1a;使用open()方法一定要保证关闭文件对象&#xff0c;即调用close(…

Python3输入输出

Python两种输出值的方式&#xff0c;表达式语句和print()函数。 第三种方式是使用文件对象的write()方法&#xff0c;标准输出文件可以用sys.stdout的引用。 如果你希望输出的形式更加多样&#xff0c;可以使用str.fomat()函数来格式化输出值。 如果你希望将输出的值转化成字符…

动态库加载顺序

1.编译目标代码时指定的动态库搜索路径&#xff1b; 2.环境变量LD_LIBRARY_PATH指定的动态库搜索路径&#xff1b; 3.配置文件/etc/ld.so.conf中指定的动态库搜索路径&#xff1b; 4.默认的动态库搜索路径/lib&#xff1b; 5.默认的动态库搜索路径/usr/lib。 转载于:https://ww…

Python3正则表达式

正则表达式是一个特殊的字符序列&#xff0c;他能帮助你方便的检查一个字符串是否与某种模式匹配。re.match函数 re.match尝试从字符串的起始位置匹配一个模式&#xff0c;如果不是起始位置匹配成功的话&#xff0c;match()就返回一个none。 函数语法&#xff1a; re.match(pat…

C/C++输入

fgets(str,n,stdin) 从键盘输入一行&#xff0c;替代gets()。读取到n-1字节时或换行符时终止&#xff0c;如果是文件的话&#xff0c;读到文件结尾也会停止 getline(cin,str) str的类型必须是string类&#xff0c;它是C特定的字符串类&#xff0c;区别于C的char *数据类型。 ci…

strlen和sizeof的区别

C语言中没有字符串&#xff0c;用的是字符数组来模拟字符串。 C风格的字符串时字符数组然后在末尾加0表示结尾。 在C语言中有strlen和sizeof两个函数求字符数组的长度函数&#xff0c;他们俩的区别就是是否把最后的结束标志也加上去。 strlen是不加的&#xff0c;他表示字符串的…

shell编程练习题

求2个数之和计算1-100的和将一目录下所有的文件的扩展名改为bak编译当前目录下的所有.c文件&#xff1a;打印root可以使用可执行文件数&#xff0c;处理结果: roots bins: 2306打印当前sshd的端口和进程id&#xff0c;处理结果: sshd Port&&pid: 22 5412输出本机创建20…

shell编程题(一)

求2个数之和 #!/bin/bashfunction add {if(( $# < 2 )); thenecho "The arg int correct"elsesum$(($1$2))echo $sumfi }add 1 add 1 2 运行结果&#xff1a; exbotubuntu:~/shareWin/linux/shell$ ./sum.sh 1 2The arg int correct3 $#&#xff1a;相当于C语言…

vimset

vim ~./vimrc set nocompatible "去掉有关vi一致性模式&#xff0c;避免以前版本的bug和局限 set nu! "显示行号 set guifontLuxi/ Mono/ 9 " 设置字体&#xff0c;字体名称和字号 filetype on …

shell编程题(二)

计算1-100之和 #!/bin/bashsum0 for i in seq 1 100;do #符号不是单引号 是 1左边的符号sum$[$i $sum ] done echo $sum #!/bin/bashi0 n1              #定义循环变量 while [ $n -lt 101 ];do  #循环变量小于101 i$(( $i $n))        #累加 n$(( …

vim命令大全

1. vim模式 正常模式&#xff08;按Esc或Ctrl[进入&#xff09; 左下角显示文件名或为空 插入模式&#xff08;按i进入&#xff09; 左下角显示--INSERT-- 可视模式&#xff08;按v进入&#xff09; 左下角显示--VISUAL-- 替换模式&#xff08;按r或R开始&#xff09; 左下角显…

signal()函数

函数原型 void (*signal(int sig,void(*func)(int)))(int); 指定使用sig指定的信号编号处理信号的方法。参数func指定程序可以处理信号的三种方式之一&#xff1a; l 默认处理(SIG_DFL)&#xff1a; 信号由该特定信号的默认动作处理l 忽略信号&#xff08;SIG_IGN&a…

setitimer()函数

定时器时间函数 struct itimerval&#xff1a;struct itimerval *new_value&#xff0c;其定义如下&#xff1a;struct itimerval {struct timeval it_interval; /*next value*/struct timeval it_value; /*current value*/};struct timeval {long tv_sec; /*seconds*/lonng t…

shell编程题(三)

将一目录下所有的文件的扩展名改为bak #! /bin/bashfor i in ls domv $i ${i%%.*}.bak done ${i%%.*} 截掉一个变量字符串第一个"."以及其右侧的所有字符&#xff0c;即最短前缀匹配。 #! /bin/bashdir./ #指定文件夹for file in $dir*.txt #指定文件夹下面文件类型…

VMware安装VMwaretools

默认点击“安装VMware Tools&#xff08;T&#xff09;”选项下载好安装包 下载的安装包放在计算机的media目录下 进入/media/ubuntu14-04/VMware Tools目录&#xff1a; cd /media/ubuntu14-04/VMware Tools 将安装包复制到tmp文件夹下&#xff1a; cp VMwareTools-10.0.5-322…

shell编程题(四)

编译当前目录下的所有.c文件 #!/bin/bashif [ $# -lt 1 ] ;then #如果输入参数小于1则报错 $# C语言中的argv[0] 输入参数个数echo "Please follow up file.c!"echo "eg: ./make.sh xxx.c"exit fiif [[ $2 "debug" ]] ;then #如果第三个参数…

stat函数

int lstat(const char *path,struct stat*buf) 当文件是一个符号链接时&#xff0c;lstat返回的是该符号链接本身的信息&#xff0c;而stat返回的是该链接指向的文件的信息。 struct stat {dev_t st_dev; //设备号码ino_t st_ino; //inode节点号mo…