分类:
2011-07-29 07:35:47
原文地址:sed和awk的简单使用 作者:hanlenry
今天要写的东西,比较不容易理解,不过我会通过一些例子,让你有一个清楚的了解的,不用太担心了,嘿嘿!首先给大家说一下我要总结的什么吧,sed命令和awk命令。Ok,来吧。
1.sed 本身也是一个管道命令,可以分析standard input的,而且sed还可以将数据替换、删除、新增、选取特定行等功能。没有破坏性,不会修改源文件内容。
sed 命令的使用格式:(1)sed [options] /pattern/command files...
模式用斜线隔开,可以使用正则表达式
(2)sed [options] ‘address1,address2command’ files...
address表示从文章中的第几行到第几行(地址范围)
options: -n 表示只显示经过处理的信息,如果不加-n,则会将来自stdin的数据全部显示到屏幕上。
-e 表示直接在命令行模式上进行sed动作编辑。要想使用多个动作,则每个动作前都要加-e参数。
-i 表示直接修改读取的文件内容,而不是有屏幕输出,是个很危险的参数。
-f 直接将sed的动作写在一个文件内,一行一个的方式写进文本文件,例如:nano script,sed -f script /proc/cpuinfo 则可以执行script内的sed动作
commad:p(打印) sed -n '/cache/p' /proc/cpuinfo
sed -n '/cache/,/wp/p' /proc/cpuinfo 从以cache的行到以wp结束的行
sed -n '1,3p' /proc/cupinfo 显示第一行到第三行的信息
sed -n '1p' /proc/cupinfo 只显示第一行的信息
sed '1,$p' /proc/cupinfo
-n要和p一块使用,才能显示你所搜索的内容。
d(删除) sed‘/^[Cc]/d' /proc/cupinfo
a(之后添加) sed‘/^processor/a#this is my cpu.’ /proc/cpuinfo
i(之前添加) sed‘/^processor/i#this is my cpu.’ /proc/cpuinfo
可以添加多行 sed‘/^processor/a#this is my cpu.\n#haha’ /proc/cpuinfo
s(替换),g(在行内进行全局替换) sed ‘addr1,addr2s/ / /g’
sed ‘1,$s/yes/YES/g' /proc/cpuinfo ($表示最后一行)
sed ‘1,$s/\bc/C/g' /proc/cpuinfo
sed ‘1,$s/\b[cC]pu\b/&s/g' /proc/cupinfo
sed ‘1,$s/\b[cC][[:alpha:]]*\b/&s/g' /proc/cpuinfo
其中&是sed所支持的正则表达式的元字符,意思是保存查找串以便在替换串中引用。例如:s/apple/&phone/,则字符串apple将替换为applephone。
练习:
1.将/etc/inittab文件中以id开头后面跟了两个冒号且两个冒号中间有一个数字,把数字改为3
sed ‘1,$s/^id:[0-9]:/id:3:/g’ /etc/inittab
2.将/etc/passwd文件中以n开头的所有单词的词首字母改为大写。
sed '1,$s/\bn\([[:alpha:]]*\)\b/N\1/g' /etc/passwd
3.在/proc/meminfo文件中所有以Hugepages开头的行后面添加”# For performancing”一个新行。
sed '/^HugePages/a#For performancing' /proc/meminfo
4.删除/etc/inittab文件中所有以#开头,或者以一些空白字符后跟一个#开头的行,并且将所有以一个空格后跟一个数字结尾的行中的那个行尾的数字改为0.
sed -e '/^[[:space:]]*#/d' /ect/inittab -e '1,$s/ [0-9]$/ 0/g'
5.将/var/目录下所有文件的文件名的首字母和尾字母显示时改为大写。
在写这个脚本时,还需要tr命令。那我们先来说说tr命令的用法
tr命令,转化字符
tr [options] 'ab' 'AB'把小写改为大写
好,那我们开始写这个脚本:
for FILE in `ls /var`;do
F=`echo $FILE |sed '1,$s/^\([[:alpha:]]\).*/\1/' |tr 'a-z' 'A-Z'`
L=`echo $FILE |sed '1,$s/^.*\([[:alpha:]]\)$/\1/' |tr 'a-z' 'A-Z'`
echo $FILE |sed "s/[[:alpha:]]\(.*\)[[:alpha:]]/$F\1$L/g"
done
运行结果:
6.写一个脚本
1)假设某个文件中有如下行:
/etc/inittab
/etc/pam.d/sudo
/usr/share/doc
/usr/local/
/etc/sysconfig/
/var/log/messages
2)取出如上文件中的每一行文件名中不包含路径的文件名,比如:/etc/inittab的文件名为inittab,/etc/sysconfig的文件名为sysconfig;
3)把每个文件名的第二个字母显示时改为大写;
nano file.txt,将上述的文件写进来
FILE=`sed '1,$s@.*/\([a-zA-Z]\{1,\}\)/\{0,1\}$@\1@g' file.txt`
for F in $FILE;do
S=echo $F | sed '1,$s/.\([a-zA-Z]\).*/\1/g' |tr 'a-z' 'A-Z'
echo $F |sed "s@\(.\).\(.*\)@\1$S\2@g"
done
你是不是奇怪怎么会出现@,@是什么东西呢?其实在替换中,你可以将s///g,写成s@ @ @g,效果是一样的,只是为了方便我们书写和读取。如果用“/”会和转义符“\”混在一起,很难分辨。
来看一下结果吧。
7.使用sed命令将/etc/yum.repos.d/server.repo文件中的字符串修改为要求直接修改原文件
sed -i '1,$s@ftp://instructor.example.com/pub@' /etc/yum.repos.d/server.repo
2.awk 文本处理命令,nawk
gnu awk =gawk
awk命令的使用格式:awk options ‘program’file
program:pattern{action}
awk 能够对行进行切片, $1 就是第一片的内容,$2就是第二片的内容,$0就是整行,默认是空格作为分隔符。awk以行为一次处理的单位,而以字段(片)为最小的处理单元
动作:print可以显示字段
awk '{print $2}' /etc/fstab 所有的action要用{}括起来,并且加单引号
pattern: 1./regular expression/
awk '/^[a-z]/{print $2}' /etc/fstab
2.expression
3.pat1,pat2
4.BEGIN修改内置变量,End只执行一次
awk 'BEGIN{print "devices mount on"}{print $2}' /etc/fstab
内建变量有以下几个:
1.FS 改变字段分隔符(默认是空格)
tail -10 /etc/passwd |awk '{FS=":"}{print $1,$3}'
怎么第一行没有正确显示呢?这是因为我们读入第一行的时候,那些变量$1,$2还是以空格键为分隔符的,所以虽然我们定义了FS=“:”了,但是却仅能在第二行后才开始生效,此时,我们可以使用BEGIN,使它开始就生效。如:
tail -10 /etc/passwd |awk 'BEGIN{FS=":"}{print $1,$3}'
2.RS 改变行分隔符
tail -10 /etc/passwd |awk 'BEGIN{FS=":";RS=";"}{print $1}'
3.OFS 显示给别人看的时候是以什么作为字段分隔符的
tail -10 /etc/passwd |awk 'BEGIN{FS=":";OFS="@"}{print $1,$6,$7}'
4.ORS 显示给别人看的时候是用什么作为行分隔符
tail -10 /etc/passwd |awk 'BEGIN{FS=":";OFS="@";ORS=”;”}{print $1,$6,$7}'
当多个内置变量一起使用时,要用分号隔开,
5.NF可以显示总共有多少字段
NR可以显示是第几行
tail -10 /etc/passwd |awk 'BEGIN{FS=":"; OFS="-"}{print NF NR $1,$3}'