Linux下的文本处理工具
文本搜索工具:grep, egrep, fgrep
globbing: 文件名通配
*, ?, [], [^]
p*[0-9]*[^0-9]
既限定了长度,又限定了可用的字符范围
过滤条件:以行为独立单位
The first line.
模式(pattern):以正则表达式的元字符,以及正常字符组合而成
文本处理工具:grep, egrep, sed, awk, vim, nginx
grep:
Global search REgular expression and Print out the line.
文本搜索工具,根据用户指定的文本模式(正则表达元字符以及正常字符组合而成)对目标文件进行逐行搜索,显示能匹配到的行;
grep命令:
grep [OPTIONS] PATTERN [FILE...]
--color[=WHEN], --colour[=WHEN]
auto
always
never
例子:grep --color=auto "root" /etc/passwd
-o: 只显示被模式匹配到的内容
-i: ignore case,不区分字符大小写
-v: 显示不能够被模式匹配到的行
-E:使用扩展的正则表达式
-A #:
-B #:
-C #
正则表达式:REGular EXPression REGEXP
是由元字符及正常字符所书写的模式,其中的元字符不表示字符本身的意义,而是用于表达控制或通配等功能;
基本正则表达式: grep
扩展正则表达式: grep -E, egrep
fgrep: fast, 不支持使用正则表达式
基本正则表达式元字符:
字符匹配:
. :匹配任意单个字符
[]: 匹配指定范围内的任意单个字符
[^]: 匹配指定范围外的任意单个字符
[0-9], [[:digit:]], [^0-9], [^[:digit:]]
[a-z], [[:lower:]]
[A-Z], [[:upper:]]
[[:space:]]
[[:punct:]]
[0-9a-zA-Z], [[:alnum:]]
[a-zA-Z], [[:alpha:]]
次数匹配:在期望匹配字符后面提供一个控制符,用于表达匹配其前面字符指定的次数
* : 任意长度,表示0次、1次或多次;
"ab*c"
abbc, ac
abb,
.*: 任意长度的任意字符
工作于贪婪模式
\?:0次或1次;表示其左侧字符可有可无
"ab\?c"
abbc,
ac, abc
\+: 1次或多次;表示其左侧字符至少出现1次;
"ab\+c"
ac,
abc, abbbbc
\{m\}:m次;表示其左侧字符精确出现m次;
\{m,n\}:至少m次,至多n次;
ab\{2\}c
ac, abc, abbbc
abbc
ab\{0,3\}c
ac, abbbc,
abbbbbc
\{0,n\}:至多n次;
\{m,\}:至少m次;
位置锚定:
^: 锚定行首
^PATTERN
$: 锚定行尾
PATTERN$
^PATTERN$:用模式来匹配整行;
# grep "^[[:space:]]*$" /etc/rc.d/rc.sysinit
^$: 匹配空白行;
单词锚定:由非特殊字符组成的连续的字符串
\< :锚定词首,也可用\b
\<PATTERN, 或\bPATTERN
# grep "\<sh" /etc/passwd
\> :锚定词尾,也可以用\b
PATTERN\>, 或PATTERN\b
\<PATTERN\>:匹配PATTERN能匹配到的整个单词
# ifconfig | grep "\<[0-9]\{2\}\>"
分组:\(\)
注意:分组中的模式,在某次的具体匹配过程中所匹配到的字符,可以被grep记忆(保存于内置的变量中,这些变量是\1, \2, ...),因此,还可以被引用;
\1: 引用,模式中自左而右,由第一个左括号以及与之对应的右括号中的模式所匹配到的内容;
\1: 引用 ,模式中自左右,由第二个左括号以及与之对应的右括号中的模式所匹配到的内容
\(ab\(cd\)mn\) \1 \2
“\(a.b\).*\1"
amb hello anb
He like his lover.
He like his liker.
She love her lover.
She love her liker.
"\(l..e\).*\1"
play.php?a.mp3?search?a.wmv
play.php?where.mp3?hello?when.wmv
\(.*\)\.mp3.*\1\.wvm
练习:
1、显示/proc/meminfo文件中以大写或小写S开头的行;用两种方式;
# grep "^[sS]" /proc/meminfo
2、显示/etc/passwd文件中其默认shell为非/sbin/nologin的用户;
# grep -v "/sbin/nologin$" /etc/passwd | cut -d: -f1
3、显示/etc/passwd文件中其默认shell为/bin/bash的用户;
# grep "/bin/bash$" /etc/passwd | cut -d: -f1
4、找出/etc/passwd文件中的一位数或两位数;
# grep "\<[0-9]\{1,2\}\>" /etc/passwd
5、显示/boot/grub/grub.conf中以至少一个空白字符开头的行;
# grep "^[[:space:]]\+" /boot/grub/grub.conf
6、显示/etc/rc.d/rc.sysinit文件中以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;
# grep "^#[[:space:]]\+[^[:space:]]\+" /etc/rc.d/rc.sysinit
7、打出netstat -tan命令执行结果中以‘LISTEN’,后或跟空白字符结尾的行;
# netstat -tan | grep "LISTEN[[:space:]]*$"
8、添加用户bash, testbash, basher, nologin (此一个用户的shell为/sbin/nologin),而后找出当前系统上其用户名和默认shell相同的用户的信息;
# grep "^\([[:alnum:]]\+\>\).*\1$" /etc/passwd
扩展的正则表达式:
字符匹配:
.
[]
[^]
次数匹配:
*: 任意次
?:0或1次
+: 至少1次
{m}:精确匹配m次;
{m,n}:至少m次,至多次;
{m,}:至少m次;
{0,n}:至多次;
位置锚定:
^
$
\<, \b
\>, \b
分组:
()
引用:\1, \2, ...
或者:
a|b:a或者b
或者两侧的所有内容;
命令:
grep -E PATTERN FILE...
egrep PATTERN FILE...
练习:
1、显示/proc/meminfo文件中以大写或小写S开头的行;用三种方式;
# grep -E "^[sS]" /proc/meminfo
# grep -E "^(s|S)" /proc/meminfo
# egrep -i "^s" /proc/meminfo
2、显示/etc/passwd文件中其默认shell为非/sbin/nologin的用户;
# egrep -v "/sbin/nologin$" /etc/passwd | cut -d: -f1
3、显示/etc/passwd文件中其默认shell为/bin/bash的用户;
# egrep "/bin/bash$" /etc/passwd | cut -d: -f1
4、找出/etc/passwd文件中的一位数或两位数;
# egrep --color=auto "\<[0-9]{1,2}\>" /etc/passwd
5、显示/boot/grub/grub.conf中以至少一个空白字符开头的行;
# egrep "^[[:space:]]+" /boot/grub/grub.conf
6、显示/etc/rc.d/rc.sysinit文件中以#开头,后面跟至少一个空白字符,而后又有至少一个非空白字符的行;
# egrep "^#[[:space:]]+[^[:space:]]+" /etc/rc.d/rc.sysinit
7、打出netstat -tan命令执行结果中以‘LISTEN’,后或跟空白字符结尾的行;
# netstat -tan | egrep "LISTEN[[:space:]]*$"
8、添加用户bash, testbash, basher, nologin (此一个用户的shell为/sbin/nologin),而后找出当前系统上其用户名和默认shell相同的用户的信息;
# egrep "^([[:alnum:]]+\>).*\1$" /etc/passwd
9、显示当前系统上root、fedora或user1用户的默认shell;
# grep -E "^(root|fedora|user1)\>" /etc/passwd | cut -d: -f7
10、找出/etc/rc.d/init.d/functions文件中某单词后面跟一组小括号的行,形如:hello();
# grep -o -E "\<[[:alnum:]]+\>\(\)" /etc/rc.d/init.d/functions
11、使用echo命令输出一个绝对路径,使用grep取出其基名;
扩展:取出其路径名
# echo /etc/rc.d/init.d/functions | grep -o -E "[[:alnum:]]+/?$" | cut -d/ -f1
12、找出ifconfig命令结果中的1-255之间数字;
# ifconfig | grep -E "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>"
13、挑战题:写一个模式,能匹配合理的IP地址;
1.0.0.1 -- 239.255.255.255
14、挑战题:写一个模式,能匹配出所有的邮件地址;
回顾:
基本正则表达式与grep:
grep [OPTIONS] PATTERN [FILE]...
-v, -o, -i, --color, -E, -A #, -B #, -C #
基本正则表达式:
字符匹配:., [], [^]
次数匹配:*, \+, \?, \{\}
锚定符:^, $, \<, \>
分组和后向引用:\(\), \1, \2, ...
扩展正则表达式与egrep
扩展正则表达式:
字符匹配:., [], [^]
次数匹配:*, +, ?, {}
锚定符:^, $, \<, \>
分组和引用:(), \1, \2, ...
或者: a|b
博客:grep, egrep及相应的正则表达式用法详解
5w1h: what, why, when, who, where, how
文件查找工具:
文件:根据文件的种属性去找到相应文件
文件查找工具:locate, find
locate:根据此前updatedb命令生成的数据库来完成文件查找
查找速度很快
非实时查找,结果不精确;模糊查找;
必要时,可手动执行updatedb命令;
find命令:通过遍历指定的目标目录,实时查找符合指定属性的文件;
精确匹配;速度略慢;
find [OPTIONS] [查找路径] [查找条件] [处理动作]
查找路径:默认为当前路径;
查找条件:默认为指定路径下的所有文件;
处理动作:默认为打印至屏幕;
查找条件:
-name "文件名":文件名支持使用globbing
*, ?, [], [^]
# find /etc -name "passwd*"
-iname "文件名"
-user USERNAME: 根据属主查找
-group USERNAME: 根据属组查找
-uid UID: 根据指定UID查找;
-gid GID: 根据指定GID查找;
-nouser: 查找没有属主的文件;
-nogroup:查找没有属组的文件;
组合查找条件:
与:-a, 查找条件1 -a 查找条件2 -a ...
所有条件必须同时满足
或:-o, 查找条件1 -o 查找条件2 -o ...
满足其中一个条件即可
非:-not, !
-not 查找条件
# find /tmp -nouser -a -name "*centos*" -ls
# find /tmp -not \( -name "*.txt" -o -name "*.out" \)
# find /tmp -not -name "*.txt" -a -not -name "*.out"
查找条件(2)
-type TYPE: 根据文件类型查找
f: 普通文件
d: 目录文件
l: 符号链接文件
b: 块设备
c: 字符设备文件
p: 命令名管道文件
s: 套接字文件
-size [+|-]#UNIT:
常用单位有:k, M, G
#UNIT: #-1 < x <= #
2k:1.8k, 1.9k, 1.1k
-#UNIT:x <= #-1
-2k: 1k, 0.9k
+#UNIT: x > #
+2k: 2.1k, 3.1k
根据时间戳查找:
以“天”为单位
-atime [+|-]#
#: #= < x < #+1
-#: x < #
+#: x >= #+1
-mtime [+|-]#
-ctime [+|-]#
以“分钟”为单位
-amin [+|-]#
-mmin
-cmin
根据权限查找:
-perm [+|-]MODE
MODE: 与MODE精确匹配
+MODE:任何一类用户的权限只要能包含对其指定的任何一位权限即可;
-MODE:每一类用户的权限都包含对其指定的所有权限;
-222,666,664
练习:
1、查找/var目录下属主为root,且属组为mail的所有文件或目录;
# find /var -user root -a -group mail -ls
2、查找当前系统上没有属主或属组的文件;
进一步:查找当前系统上没有属主或属组,且最近3天内曾被访问过的文件或目录;
# find / \( -nouser -o -nogroup \) -a -atime -3
3、查找/etc目录下所有用户都有写权限的文件;
# find /etc -perm -222 -ls
进一步:查找/etc/目录下所有用户都没有写权限的文件;
# find /etc -not -perm +222
4、查找/etc目录下大于1M,且类型为普通文件的所有文件;
# find /etc -size +1M -a -type f
5、查找/etc/init.d/目录下,所有用户都有执行权限,且其它用户有写权限的文件;
# find /etc/init.d/ -perm -113
6、查找/usr目录下不属于root、bin或hadoop的文件;
# find /usr -not -user root -a -not -user bin -a -not -user hadoop -ls
# find /usr -not \( -user root -o -user bin -o -user hadoop \) -ls
7、查找/etc/目录下至少有一类用户没有写权限的文件;
# find /etc -not -perm -222
8、查找/etc目录下最近一周内其内容被修改过,且不属于root或hadoop的文件;
# find /etc -mtime -7 -a -not \( -user root -o -user hadoop \)