Linux bash总结(二) 高级部分(适合初学者学习和非初学者参考) (持续更新中...)
版本号 | 说明 | 作者 | 日期 |
1.0 | 添加awk和sed的说明 | Sky Wang | 2013/05/31 |
1.1 |
(01) 添加正则表达式(第3部分) (02) 修改awk中错误内容 |
Sky Wang | 2013/06/05 |
本文主要通过实例对bash中需要用到的一些高级工具(如awk、sed、...)进行说明。学习的时候,请以“应用实例”为中心,以其它内容为参考进行学习。如果遇到文章中未讲解的内容,可以通过man去查阅用法。
转载请注明出处:Linux bash总结(二) 高级部分(适合初学者学习和非初学者参考) (持续更新中...)
第一部分 awk工具
本章主要通过awk的一些应用实例,来说明awk的相关语法。这样,更利于我们进行理解;所以,阅读本章时,请以“应用实例”为中心进行阅读,其它部分是参考内容。
1 awk介绍
awk是一种用于处理文本的编程语言工具。awk本身就是linux下的一个工具,既可以单独使用,也可以嵌入到bash中。
awk语言的最基本功能是在文件或字符串中基于指定规则浏览和抽取信息。 awk抽取信息后,才能进行其他文本操作。完整的 awk脚本通常用来格式化文本文件中的信息。
2 awk环境变量
3 awk条件操作符
4 awk字符串操作
5 正则表达式中常用类
6 awk应用实例
首先建立一个123.txt,添加任意文本,然后进行以下练习。
(01), 输出文件全部文本
$ awk '{print $0}' 123.txt
说明:
{}:表示一段awk命令。
print:输出指令。
$0:当前行的全部文本。
awk工具操作文件时,是以行为单位,逐步对每行进行操作。拿本例来说{print $0},意味着“对每一行都执行print $0操作,即输出每一行的全部文本”。
$N:当N>1时,$N表示当前行的第N段;每一行中以FS(默认值是空格)来分段。
(02), 输出"ls -l"中每行的field1、field9
$ ls -l | awk '{printf("%s %s\n", $1, $9)}'
说明:
|:管道符号。表示将“前面指令的输出”作为“后面指令的输入”,即将“ls -l”的输出作为“awk”的输入。
printf:输出指令。它的使用方法和C语言中printf的使用方法一样。
$1:该行的第1段。
$9:该行的第9端。
(03), 在上一题的基础上添加功能:第一,输出每一行的行号和该行所包括的域的总数。第二,第1行和最后一行输出提示语
$ ls -l | awk 'BEGIN{printf("----begin----\n")} {printf("Line-%3d Field-%d : %s %s\n", NR, NF, $1, $9)} END{printf("----end----\n")}'
说明:
BEGIN:表示在文本进行操作之前进行的工作。
END:表示在对文本的所有行都处理完毕之后前进行的工作。
在awk中,请尽量使用{}来进行区分指令段,{}可以嵌套使用!这样做的好处写出的脚本不容易出错,而且可读性更强!
(04), 输出"ls -l"中文件(夹)名字包括数字的完整信息
$ ls -l | awk '{if($9 ~ /[[:digit:]]/) {print $0}}'
说明:
$9 ~ /[[:digit:]]/ : 表示能够匹配数字的“第一行的第9段”。
(05), 输出"ls -l"中非文件夹的完整信息
$ ls -l | awk '{if($1 !~ /^d/) {print $0}}'
说明:
^d : 以d开头的。^表示起始位。此外,$表示结束位。如d$,表示以d结尾的。
(06), 找到"ls -l"中文件(夹)名字的长度大于10的行,然后输出其完整信息。
$ ls -l | awk '{if(length($9) > 10) {print $0}}'
(07), 如何给文本的每一行添加行号?
$ awk '{printf("%03d %s\n",NR, $0)}' ori.txt > dst.txt
(08), 打印字段数大于3的行的总数
$ awk 'BEGIN{COUNT=0}; {if(NF>3) COUNT++}; END{printf("COUNT=%d\n", COUNT)}' ori.txt
(09), 将文本中的各行合并一行,中间用“|”分割
$ awk 'BEGIN{ORS="|"}{print $0 }END{print "\n"}' ori.txt > dst.txt
说明:
ORS:表示记录分割符,每条记录表示每行。ORS默认值为换行符。
(10), 将文本中空格换成换行符
$ awk 'BEGIN{FS=" ";OFS="\n"}{print $1 }END{print "\n"}' ori.txt > dst.txt
(11), 将3行合并成一行,并输入行号
$ awk 'BEGIN{ORS="";i=0}{ j=1; while(j<=NF){ if(i%3==0){printf("%02d ",i/3+1)}; printf("%s ",$j); i++; j++; if(i%3==0){print "\n"} }} END{print "\n"}' ori.txt > dst.txt
第二部分 sed工具
和awk一样,本章主要通过实例对sed进行介绍。这样,更利于我们进行理解;所以,阅读本章时,请以“应用实例”为中心进行阅读,其它部分是参考内容。
1 sed介绍
sed是一个非交互性文本流编辑器。和awk一样,它是个独立的工具,当然也可以和bash联合使用。
它可以随意编辑文件或标准输入,对它们进行编辑、删除。它能一次性处理所有改变,对用户来讲,十分高效。sed编辑文件或标准输入时,编辑的是它们的拷贝;也就是说,不会改变原始的文件。若需要保存修改,可以通过重定向操作符>>、>>>,或者在利用sed的写入参数。
2 基本格式
sed [选项] 输入文件
-n 不打印;sed不写编辑行到标准输出,缺省为打印所有行(编辑和未编辑)。
-p 命令可以用来打印编辑行。
-c 下一命令是编辑命令。使用多项编辑时加入此选项。如果只用到一条 sed命令,此选项无用,但指定它也没有关系。
-e 追加执行脚本
-f 如果正在调用 sed脚本文件,使用此选项。
3 使用sed在文件中定位文本的方式
如下表:
4 sed编辑命令
如下表:
5 应用实例
首先建立一个123.txt,添加任意文本,然后进行以下练习。
(01), 输出文件第5行
$ sed -n '5p' 123.txt
说明:
-n表示默认不输出任何内容。5p表示输出第5行:5表示第5行,p表示输出。
(02), 输出文件除1-3行之外的行
$ sed -n '1,3!p' 123.txt
说明:
"1,3"表示输出范围是第1-3行; "1,3!"表示输出范围是除第1-3行之外。
'1,$p'表示输出全部行,因为$表示最后一行。
(03), 输出"ls -l"结果中的第1-3行
$ ls -l |sed -n '1,3p'
说明:
|是管道符号,表示将ls -l的输出作为sed的输入。
(04), 输出匹配“the”的行
$ sed -n '/the/p' 123.txt
说明:
/the/表示匹配the的行
(05), 输出匹配“the”的行,并且输出每行行号
$ sed -n -e '/the/p' -e '/the/=' 123.txt
说明:
-e表示对每行进行多重编辑,多重编辑的每一个命令前都需要添加-e。
本例中,-e '/the/p'打印匹配the的行;-e '/the/='表示输出匹配the的行的行号。
(06), 删除匹配“the”的行
$ sed '/the/d' 123.txt
说明:
d表示删除。
(07), 删除匹配“the”的行;然后输出删除操作之后的所有行,并输出每行行号
$ sed '/the/d' 123.txt | sed -n -e '1,$p' -e '1,$='
说明:
sed '/the/d' 123.txt :得到了删除“the”之后的行
| :管道符号。意味着前面的输出作为后面的输入
sed -n -e '1,$p' -e '1,$=' :表示输出全部行之后,在输出每行行号
(08), 在每一行前面插入2行文本,第一行是line1,第2行是line2
$ sed '1,$iline1\nline2' 123.txt
说明:
1,$i表示第一行到最后一行的每一行都执行插入操作。
line1\nline2表示插入的文本,其中\n转义之后表示“换行”符号。
(09), 在最后一行后面插入1行文本,内容是end
$ sed '$aend' 123.txt
说明:
$表示最后一行,a表示在文本后插入,end是插入的内容
(10), 将“this”全部替换成“that”
$ sed 's/this/that/g' 123.txt
说明:
[ address[,address ] ] s / pattern-to-find / replacement-pattern/[gpwn]
s 表示替换操作。查询pattern-to-find,成功后用replacement-pattern替换它。
替换选项如下:
g 缺省情况下只替换每行的第一次匹配,g表示替换每行的所有匹配。
p 缺省sed将所有被替换行写入标准输出,加p选项将使-n选项无效。-n选项不打印输出结果。
w 后接“文件名”,表示将输出定向到一个文件。
(11), 将“this”全部替换成“this boy”
$ sed 's/this/this boy/g' 123.txt 或 $ sed 's/this/boy &/g' 123.txt
说明:
sed 's/this/boy &/pg' 123.txt中&表示附加修改(即在原始内容的基础上添加内容)。
&表示匹配的内容。即,boy &等价于boy this
(12), 去掉空白行后另存文件
$ sed '/^$/d' 123.txt > 456.txt 或 $ sed '/^$/c\' 123.txt > 456.txt
说明:
/^$/表示空白行:^表示开启,$表示结尾,开始和结尾之间没有任何内容,即是空白行。
c\表示修改。
(13), 去掉文件扩展名
$ echo "hello.txt"| sed 's/.txt//g'
(14), 添加文件扩展名
$ echo "hello"| sed 's/$/.txt/g'
(15), 删除文本中每一行的第2个字符
$ sed 's/.//2' ori.txt > dst.txt
(16), 删除文本中每一行的倒数第2个字符
$ sed 's/\(.\)\(.\)$/\2/' ori.txt > dst.txt
#说明:考察了sed中"\( \)"的含义和用法
(17), 删除每一行的第2个单词
$ sed 's/\([[:alpha:]]\+\)\(\ \)\([[:alpha:]]\+\)*/\1/' ori.txt > dst.txt
(18), 隔行删除
$ sed '0~2 d' ori.txt > dst.txt
第三部分 正则表达式和grep
本章主要通过一些应用实例,来对正则表达式进行说明。
1 正则表达式
正则表达式就是字符串的表达式。它能通过具有意义的特殊符号表示一列或多列字符串。
grep是linux系统下常用的正则表达式工具,可以使用grep来检索文本等输入流的字符串。
2 正则表达式特殊符号
参考下面表格
3 grep表达式
基本格式
grep [OPTIONS] PATTERN [FILE...]
格式说明
PATTERN : 匹配模式。可以是字符串,也可以是正则表达式。
[FILE...] : 是grep搜索的文件(集)
[OPTIONS] : 是grep的选项。常用的选项有以下选项。
-c : 只输出匹配行的计数。
-I : 不区分大 小写(只适用于单字符)。
-h : 查询多文件时不显示文件名。
-l : 查询多文件时只输出包含匹配字符的文件名。
-n : 显示匹配行及 行号。
-s : 不显示不存在或无匹配文本的错误信息。
-v : 显示不包含匹配文本的所有行。
-r : 当FILE中包含文件夹名时,遍历该文件夹的所有子目录;默认情况下,不会遍历子目录。
4 应用实例
下面以input.txt为例,对grep进行说明。input.txt的文本内容如下:
"Open Source" is a good mechanism to develop programs. apple is my favorite food. Football game is not use feet only. this dress doesn't fit me. However, this dress is about $ 3183 dollars.^M GNU is free air not free beer.^M Her hair is very beauty.^M I can't finish the test.^M Oh! The soup taste good.^M motorcycle is cheap than car. This window is clear. the symbol '*' is represented as start. Oh! My god! The gd software is a library for drafting programs.^M You are the best is mean you are the no. 1. The world <Happy> is the same with "glad". I like dog. google is the best tools for search keyword. goooooogle yes! go! go! Let's go
(01), 查找包含“the”的行,并显示行号。
$ grep -n "the" input.txt
说明:-n表示显示“行号”
(02), 不区分大小写,查找包括“the”的行,并显示行号。
$ grep -in "the" input.txt
说明:-n表示显示“行号”;-i表示不区分大小写,即ignore大小写。
(03), 查找不包括“the”的行,统计行数。
$ grep -cv "the" input.txt
说明:-c表示统计(count);-v表示不匹配的项。
(04), 查找“当前目录”及其“所有子目录”中包含“the”的文件,并显示“the”在其中的行号。
$ grep -rn "the" .
说明:-r表示递归查找;-n表示显示行号。
(05), 查找匹配“t?st”的项,其中?为任意字符。
$ grep -n "t.st" input.txt
说明:.表示匹配任意字符
(06), 查找包含数字的行
$ grep -n "[0-9]" input.txt 或 $ grep -n "[[:digit:]]" input.txt
说明:[0-9]表示0-9之间的一个数字;[[:digit:]]也表示0-9之间的一个数字
(07), 查找以the开头的行
$ grep -n "^the" input.txt
说明:"^the"表示以the开头
(08), 查找以小写字母结尾的行。
$ grep -n "[a-z]$" input.txt
说明:[a-z]表示一个小写字母,$表示结束符;[a-z]$表示以小写字母结束的项。
(09), 查找空白行。
$ grep -n "^$" input.txt
说明:^表示开头,如^t表示以字母t开头;$表示结尾,如e$表示以e结尾。^$表示空白行。
(10), 查找以字母g开头的单词
$ grep -n "\<g" input.txt
说明:\<表示单词的开始,\<g表示以g开始的单词。
(11), 查找字符串为go的单词。注意:不能包括goo,good等字符串
$ grep -n "\<go\>" input.txt
说明:\<表示单词的开始,\>表示单词结尾。\<go\>表示以字母g开头,以字母o结尾。
(12), 查找包括2-5个字母o的行。
$ grep -n "o\{2,5\}" input.txt
说明:pattern\{n,m\}表示n到m个pattern。o\{2,5\}表示2-5个字母o。
(13), 查找包括2个以上字母o(包括2个)的行。
$ grep -n "ooo*" input.txt 或 $ grep -n "oo\+" input.txt 或 $ grep -n "o\{2,\}" input.txt
说明:
ooo*: 前面两个oo表示匹配2个字母o,后面的o*表示匹配0到多个字母o。
oo\+: 第一个字母o表示匹配单个字母o;最后的“o\+”一起发挥作用,其中,\+是转义后的+,表示1到多个;而o\+表示1到多个字母o。
pattern\{n,\}表示多于n个pattern。o\{2,\}表示多于2个字母o。
4 egrep
4.1 egrep说明
egrep是扩展的grep,即它的功能比grep更多一些。"egrep"等价于"grep -e"。
egrep相比与grep,支持括号“()”以及操作符“|”(表示或)。
4.2 egrep应用实例
仍然以上面的input.txt为输入文本进行说明
(01), 查找包含the或者this的行
$ egrep -n "the|this" input.txt
说明:-n表示输出匹配项的行号,"the|this"表示包括the或者包括this的项。
(02), 查找包含the或者this的行
$ egrep -vn "(the|this)" input.txt
说明:-n表示输出匹配项的行号,"the|this"表示包括the或者包括this的项;-v表示匹配的对立面。即 -v "the|this"表示既不包括the又不包括this的项。
关于Linux bash基础部分,请参考:Linux bash总结(一) 基础部分(适合初学者学习和非初学者参考)