Shell 查找与替换

1.文本查找 searching

传统上,有3种程序可以用来查找整个文本文件
1. grep 基本正则表达式
2. egrep 扩展正则表达式
3. fgrep 快速grep,匹配固定字符串而非正则表达式,它使用优化算法,能更有效的匹配固定字符串。
后来这三个都整合到了grep中。

1.简单的grep

who | grep -F austen

使用-F选项查找固定字符串austen,事实上,只要匹配的模式里未含有正则表达式的Meta字符,则grep认行为模式就等同于使用了-F:

who | grep austen

2.正则表达

grep [options...] pattern-spec[files...]

用途 显示匹配一个或多个模式的文本行。时常会作为管道的第一步,以便对匹配的数据作进一步处理。
主要选项:
-E 使用扩展正则表达式进行匹配。grep -E 等于 egrep
-F 使用固定字符串进行匹配。grep -F 等于 fgrep
-e pat-list 通常,第一个非选项的参数会指定要匹配的模式,也可以提供多个模式,只要将他们放在引号里并以换行符分隔他们。模式以减号开头时,grep会混淆,将它视为选项。这就是-e选项派上用场的时候,可以指定其参数为模式——即使它以减号开头。
-f pat-file 从pat-file文件提取模式做匹配
-i 模式匹配时忽略字母大小写差异
-l 列出匹配模式的文件名称,而不是打印匹配的行
-q 静的。如果模式匹配成功,则grep会成功的离开,而不将匹配的行写入标准输出;否则即是不成功。
-s 不显示错误信息。通常与-q 并用。
-v 显示不匹配模式的行。
行为模式 读取命令行上指明的每个文件,发现匹配查找模式的行时,将它显示出来。当指明多个文件时,grep会在每一行前面加上文件名与一个冒号。认使用BRE(basic regular expression,基本的正则表达式)。
可以使用多个 -e -f选项,建立要查找的模式列表。

字符 BRE/ERE 模式含义
\ 两者都可 通常用来关闭后续字符的特殊意义,有时则是打开后续字符的特殊意义。如\(...\)与\{..\}
. 两者都可 匹配任何单个的字符,但NUl除外
* 两者都可 匹配在他之前的任何数目(或没有)的单个字符。如.*匹配任一字符的任意长度
^ 两者都可 匹配紧接着的正则表达式,在行或字符串的起始处
$ 两者都可 匹配前面的正则表达式,在字符串或行结尾处
[…] 两个都可 方括号表达式,匹配方括号内的任一字符,^在方括号里的第一个字符则说明匹配不在方括号内的任何字符[^A-Z]:匹配不是大写的A-Z之间的字符
\{n,m\} BRE 区间表达式,匹配在它前面的单个字符重现的次数区间。\{n\}指的是重现n次,\{n,\}为至少重现n次,\{n,m\}为重现n-m次
\( \) BRE 将(与)之间的模式存储在特殊的保留空间hoding space中,最多可存储9个独立的子模式,可通过转义序列\1到\9被重复用在相同模式里,例如(ab).*\1,指的是匹配于ab组合的两次重现,中间可能存在任何数目的字符。
\n BRE 重复在(和)括号内第n个子模式至此点的模式。n为1-9的数字,1为由左开始。
{n,m} ERE 和{n,m}一样
+ ERE 匹配前面正则表达式的一个或多个实例
ERE 匹配前面正则表达式的0个或一个实例
| ERE 匹配于|符号前或后的正则表达式
() ERE 匹配括号括起来的正则表达式群

范例:

表达式 匹配
tolstoy 位于一行上任何位置的7个字母:tolstoy
^tolstoy 7个字母tolstoy,出现在行的开头
tolstoy$ 7个字母tolstoy,出现在行的结尾
[Tt]olstoy 在一行上的任意位居中,含有Tolstoy或tolstoy
tol.toy 含有tol加上任何一个字符,再接着toy这3个字母
tol.*toy 在一行上的任意位置居中,含有tol这3个字母,加上任意的0或多个字符,再继续toy这3个字母,如toltoy,tolstoy,tolWHOtoy等

POSIX字符集:

类别 匹配字符
[:alnum:] 数字字符
[:alpha:] 字母字符
[:blank:] 空格space与定位tab字符
[:cntrl:] 控制字符
[:digit:] 数字字符
[:graph:] 非空格字符
[:lower:] 小写字母字符
[:print:] 显示的字符
[:punct:] 标点符号字符
[:space:] 空白字符
[:upper:] 大写字母字符
[:xdigit:] 十六进制数字

在方括号表达式中,所有其他的Meta字符都会失去其特殊含义。所以[*\.]匹配于字面上的星号,反斜杠以及句点。要让]进入该集合,可以将它放在列表的最前面:[]*\.],要让减号字符进入该集合,也要放到最前面[-*\.],]和-一起选择的话,]放到第一个,减号放到最后一个[]*\.-]

后向引用:
\(ab\)\(cd\)[def]*\2\1:adcdcdab,abcdeeecdab,abcdddeeffcdab,…
(why).*\1:一行里有两个why

在文本文件里进行替换

sed

一般来说,执行文本替换的正确程序应该是 sed ——流编辑器(Stream Editor),sed的设计就是用来以批处理的方式而不是交互的方式来编辑文件。当你知道要做好几个变更,比较简单的方式是将这些变更部分写到一个编辑中的脚本里,再将此脚本应用到所有必须修改文件

sed 's/:.*//' /etc/passwd | sort -u:删除一个冒号之后的所有东西,排序列表并删除重复部分。

cut

语法
cut -c list[file ...]
cut -f list[-d lelim][file...]
用途
从输入文件中选择一或多个字段或者一组字符,配合管道(pipeline),可再做进一步处理。
主要选项:
-c list
 以字符为主,执行cut操作。list为字符编号或一段范围的列表(以逗点隔开),如1,3,5-12,42
-d delim 通过-f选项,使用delim作为定界符,认为tab
-f list 以字段为主,坐剪下的操作。list为字段编号或一段范围内的列表,以逗号隔开。
$ ls -l | cut -c 1-10

使用join连接字段

语法 join [options ...] file1 file2
用途 以共同一个键值,将已存储文件内的记录加以结合。
选项:
-1 field1  
-2 field2
-1 field1 是从file1中取出字段field1,-2 field2是从file2取出field2.字段编号自1开始,而非0.
-o file.field
    输出file文件中的field字段。一般的字段则不打印。除非使用多个-o选项,即可显示多个输出字段。
-t separator:使用separator作为输入字段分隔字符,而非使用空白。此字符也为输出的字段分隔字符。
cat sales
#业务员数据
#业务员 量
joe 100
jane 200
herman 150
chris 300

cat quotas
#配额
#业务员 配额
joe   50
jane  75
herman 80
chris  95

# 为了让join得到正确结果,输入文件必须先完成排序。
merge-sales.sh
#!/bin/sh
# 删除注释并排序数据文件
sed '/^#/d' quotas | sort > quotas.sorted
sed '/^#/d' sales | sort > sales.sorted
#以第一个键值作结合,将结果产生至标准输出
join quotas.sorted sales.sorted

awk

awk 'program' [file ...]
awk程序基本架构为:
pattern {action}
...|awk '{print some-stuff}'|...
例如:
awk '{print $1}' 打印第一个字段(未指定pattern)
awk '{print $2,$5}' 打印第2与第5个字段(未指定pattern)
awk '{print $1,$NF}'打印第一个与最后一个字段,未指定pattern
awk 'NF > 0 {print $0}'打印非空行,指定pattern与action,$0表示整条记录
awk 'NF>0' 同上
awk -F: '{print $1,$5}' /etc/passwd #处理/etc/passwd,以:作为分隔符

awk -F: '{print "User",$1,"is really",$5}' /etc/passwd

相关文章

用的openwrt路由器,家里宽带申请了动态公网ip,为了方便把2...
#!/bin/bashcommand1&command2&wait从Shell脚本并行...
1.先查出MAMP下面集成的PHP版本cd/Applications/MAMP/bin/ph...
1、先输入locale-a,查看一下现在已安装的语言2、若不存在如...
BashPerlTclsyntaxdiff1.进制数表示Languagebinaryoctalhexa...
正常安装了k8s后,使用kubect工具后接的命令不能直接tab补全...