bash通配符和正则表达式
2013-05-10 15:23
218 查看
部分摘录鸟哥私房菜,部分整理汇总;
SHELL通配符与特殊符号
在 bash 的操作环境中还有一个非常有用的功能,那就是通配符 (wildcard) ! 我们利用 bash 处理数据就更方便了!底下我们列出一些常用的通配符喔:
接下来让我们利用通配符来玩些东西吧!首先,利用通配符配合 ls 找檔名看看:
除了通配符之外,bash 环境中的特殊符号有哪些呢?底下我们先汇整一下:
Bash 一些特殊变量
基础正规表达式
经过了上面的几个简单的范例,我们可以将基础的正规表示法特殊字符汇整如下:
扩展正规表达式
事实上,一般读者只要了解基础型的正规表示法大概就已经相当足够了,不过,某些时刻为了要简化整个命令操作, 了解一下使用范围更广的延伸型正规表示法的表示式会更方便呢!举个简单的例子好了,在上节的例题三的最后一个例子中,我们要去除空白行与行首为
# 的行列,使用的是
grep -v '^$' regular_express.txt | grep -v'^#'
需要使用到管线命令来搜寻两次!那么如果使用延伸型的正规表示法,我们可以简化为:
egrep -v '^$|^#' regular_express.txt
延伸型正规表示法可以透过群组功能『 | 』来进行一次搜寻!那个在单引号内的管线意义为『或 or』啦! 是否变的更简单呢?此外,grep 默认仅支持基础正规表示法,如果要使用延伸型正规表示法,你可以使用 grep -E , 不过更建议直接使用 egrep !直接区分命令比较好记忆!其实 egrep 与 grep -E 是类似命令别名的关系啦!
熟悉了正规表示法之后,到这个延伸型的正规表示法,你应该也会想到,不就是多几个重要的特殊符号吗? ^_^y 是的~所以,我们就直接来说明一下,延伸型正规表示法有哪几个特殊符号?由於底下的范例还是有使用到regular_express.txt ,不巧的是刚刚我们可能将该文件修改过了 @_@,所以,请重新下载该文件来练习喔!
以上这些就是延伸型的正规表示法的特殊字节。另外,要特别强调的是,那个 ! 在正规表示法当中并不是特殊字节, 所以,如果你想要查出来文件中含有 ! 与 > 的字行时,可以这样:
grep -n '[!>]' regular_express.txt
这样可以了解了吗?常常看到有陷阱的题目写:『反向选择这样对否? '[!a-z]'?』, 呵呵!是错的呦~要 '[^a-z] 才是对的!至於更多关於正规表示法的进阶文章,请参考文末的参考数据(
通配符和正则表达式区别
再次强调:正规表示法的特殊字符与一般在shell命令行中的通配符并不相同。
举例来说,不支持正规表示法的 ls 这个工具中,若我们使用 『ls -l * 』 代表的是任意档名的文件,而 『ls -l a* 』代表的是以 a 为开头的任何档名的文件, 但在正规表示法中,我们要找到含有以 a 为开头的文件,则必须要这样:(需搭配支持正规表示法的工具)
ls | grep -n '^a.*'
示例:
SHELL通配符与特殊符号
在 bash 的操作环境中还有一个非常有用的功能,那就是通配符 (wildcard) ! 我们利用 bash 处理数据就更方便了!底下我们列出一些常用的通配符喔:
符号 | 意义 |
* | 代表『 0 个到无穷多个』任意字符 |
? | 代表『一定有一个』任意字符 |
[ ] | 同样代表『一定有一个在括号内』的字符(非任意字符)。例如 [abcd] 代表『一定有一个字符, 可能是 a, b, c, d 这四个任何一个』 |
[ - ] | 若有减号在中括号内时,代表『在编码顺序内的所有字符』。例如 [0-9] 代表 0 到 9 之间的所有数字,因为数字的语系编码是连续的! |
[^ ] | 若中括号内的第一个字符为指数符号 (^) ,那表示『反向选择』,例如 [^abc] 代表 一定有一个字符,只要是非 a, b, c 的其他字符就接受的意思。 |
[root@www ~]# LANG=C <==由于与编码有关,先配置语系一下 范例一:找出 /etc/底下以 cron 为开头的档名 [root@www ~]# ll -d /etc/cron* <==加上 -d是为了仅显示目录而已 范例二:找出 /etc/底下文件名『刚好是五个字母』的文件名 [root@www ~]# ll -d /etc/????? <==由于 ?一定有一个,所以五个 ?就对了 范例三:找出 /etc/底下文件名含有数字的文件名 [root@www ~]# ll -d /etc/*[0-9]* <==记得中括号左右两边均需 * 范例四:找出 /etc/底下,档名开头非为小写字母的文件名: [root@www ~]# ll -d /etc/[^a-z]* <==注意中括号左边没有 * 范例五:将范例四找到的文件复制到 /tmp中 [root@www ~]# cp -a /etc/[^a-z]* /tmp |
符号 | 内容 |
# | 批注符号:这个最常被使用在 script 当中,视为说明!在后的数据均不运行 |
\ | 跳脱符号:将『特殊字符或通配符』还原成一般字符 |
| | 管线 (pipe):分隔两个管线命令的界定(后两节介绍); |
; | 连续命令下达分隔符:连续性命令的界定 (注意!与管线命令并不相同) |
~ | 用户的家目录 |
$ | 取用变量前导符:亦即是变量之前需要加的变量取代值:$param =${param} |
& | 工作控制 (job control):将命令变成背景下工作 |
! | 逻辑运算意义上的『非』 not 的意思! |
/ | 目录符号:路径分隔的符号 |
>, >> | 数据流重导向:输出导向,分别是『取代』与『累加』 |
<, << | 数据流重导向:输入导向 (这两个留待下节介绍) |
' ' | 单引号,不具有变量置换的功能 |
" " | 具有变量置换的功能! |
` ` | 两个『 ` 』中间为可以先运行的命令,等价于 $( ) |
( ) | 在中间为子 shell 的起始与结束 |
{ } | 在中间为命令区块的组合! |
变量 | 含义 |
$# | 传递到脚本的参数个数 |
$* | 以一个单字符串显示所有向脚本传递的参数。与位置变量不同,此选? |
$$ | 脚本运行的当前进程I D号 |
$! | 后台运行的最后一个进程的进程I D号 |
$@ | 与$#相同,但是使用时加引号,并在引号中返回每个参数 |
$- | 显示s h e l l使用的当前选项,与s e t命令功能相同 |
$? | 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。 |
shift n | 向左移动n个位置参数,最左边的位置参数被删除掉 |
${LINENO} | $LINENO是一个shell的内置变量,代表shell脚本的当前行号 |
经过了上面的几个简单的范例,我们可以将基础的正规表示法特殊字符汇整如下:
RE 字符 | 意义与范例 |
^word | 意义:待搜寻的字串(word)在行首! 范例:搜寻行首为 # 开始的那一行,并列出行号 grep -n '^#' regular_express.txt |
word$ | 意义:待搜寻的字串(word)在行尾! 范例:将行尾为 ! 的那一行列印出来,并列出行号 grep -n '!$' regular_express.txt |
. | 意义:代表『一定有一个任意字节』的字符! 范例:搜寻的字串可以是 (eve) (eae) (eee) (e e), 但不能仅有 (ee) !亦即 e 与 e 中间『一定』仅有一个字节,而空白字节也是字节! grep -n 'e.e' regular_express.txt |
\ | 意义:跳脱字符,将特殊符号的特殊意义去除! 范例:搜寻含有单引号 ' 的那一行! grep -n \' regular_express.txt |
* | 意义:重复零个到无穷多个的前一个 RE 字符 范例:找出含有 (es) (ess) (esss) 等等的字串,注意,因为 * 可以是 0 个,所以 es 也是符合带搜寻字串。另外,因为 * 为重复『前一个 RE 字符』的符号, 因此,在 * 之前必须要紧接著一个 RE 字符喔!例如任意字节则为 『.*』 ! grep -n 'ess*' regular_express.txt |
[list] | 意义:字节集合的 RE 字符,里面列出想要撷取的字节! 范例:搜寻含有 (gl) 或 (gd) 的那一行,需要特别留意的是,在 [] 当中『谨代表一个待搜寻的字节』, 例如『 a[afl]y 』代表搜寻的字串可以是 aay, afy, aly 即 [afl] 代表 a 或 f 或 l 的意思! grep -n 'g[ld]' regular_express.txt |
[n1-n2] | 意义:字节集合的 RE 字符,里面列出想要撷取的字节范围! 范例:搜寻含有任意数字的那一行!需特别留意,在字节集合 [] 中的减号 - 是有特殊意义的,他代表两个字节之间的所有连续字节!但这个连续与否与 ASCII 编码有关,因此,你的编码需要配置正确(在 bash 当中,需要确定 LANG 与 LANGUAGE 的变量是否正确!) 例如所有大写字节则为 [A-Z] grep -n '[A-Z]' regular_express.txt |
[^list] | 意义:字节集合的 RE 字符,里面列出不要的字串或范围! 范例:搜寻的字串可以是 (oog) (ood) 但不能是 (oot) ,那个 ^ 在 [] 内时,代表的意义是『反向选择』的意思。 例如,我不要大写字节,则为 [^A-Z]。但是,需要特别注意的是,如果以 grep -n [^A-Z] regular_express.txt 来搜寻,却发现该文件内的所有行都被列出,为什么?因为这个 [^A-Z] 是『非大写字节』的意思, 因为每一行均有非大写字节,例如第一行的 "Open Source" 就有 p,e,n,o.... 等等的小写字 grep -n 'oo[^t]' regular_express.txt |
\{n,m\} | 意义:连续 n 到 m 个的『前一个 RE 字符』 意义:若为 \{n\} 则是连续 n 个的前一个 RE 字符, 意义:若是 \{n,\} 则是连续 n 个以上的前一个 RE 字符! 范例:在 g 与 g 之间有 2 个到 3 个的 o 存在的字串,亦即 (goog)(gooog) grep -n 'go\{2,3\}g' regular_express.txt |
事实上,一般读者只要了解基础型的正规表示法大概就已经相当足够了,不过,某些时刻为了要简化整个命令操作, 了解一下使用范围更广的延伸型正规表示法的表示式会更方便呢!举个简单的例子好了,在上节的例题三的最后一个例子中,我们要去除空白行与行首为
# 的行列,使用的是
grep -v '^$' regular_express.txt | grep -v'^#'
需要使用到管线命令来搜寻两次!那么如果使用延伸型的正规表示法,我们可以简化为:
egrep -v '^$|^#' regular_express.txt
延伸型正规表示法可以透过群组功能『 | 』来进行一次搜寻!那个在单引号内的管线意义为『或 or』啦! 是否变的更简单呢?此外,grep 默认仅支持基础正规表示法,如果要使用延伸型正规表示法,你可以使用 grep -E , 不过更建议直接使用 egrep !直接区分命令比较好记忆!其实 egrep 与 grep -E 是类似命令别名的关系啦!
熟悉了正规表示法之后,到这个延伸型的正规表示法,你应该也会想到,不就是多几个重要的特殊符号吗? ^_^y 是的~所以,我们就直接来说明一下,延伸型正规表示法有哪几个特殊符号?由於底下的范例还是有使用到regular_express.txt ,不巧的是刚刚我们可能将该文件修改过了 @_@,所以,请重新下载该文件来练习喔!
RE 字符 | 意义与范例 |
+ | 意义:重复『一个或一个以上』的前一个 RE 字符 范例:搜寻 (god) (good) (goood)... 等等的字串。 那个 o+ 代表『一个以上的 o 』所以,底下的运行成果会将第 1, 9, 13 行列出来。 egrep -n 'go+d' regular_express.txt |
? | 意义:『零个或一个』的前一个 RE 字符 范例:搜寻 (gd) (god) 这两个字串。 那个 o? 代表『空的或 1 个 o 』所以,上面的运行成果会将第 13, 14 行列出来。 有没有发现到,这两个案例( 'go+d' 与 'go?d' )的结果集合与 'go*d' 相同? 想想看,这是为什么喔! ^_^ egrep -n 'go?d' regular_express.txt |
| | 意义:用或( or )的方式找出数个字串 范例:搜寻 gd 或 good 这两个字串,注意,是『或』! 所以,第 1,9,14 这三行都可以被列印出来喔!那如果还想要找出 dog 呢? egrep -n 'gd|good' regular_express.txt egrep -n 'gd|good|dog' regular_express.txt |
() | 意义:找出『群组』字串 范例:搜寻 (glad) 或 (good) 这两个字串,因为 g 与 d 是重复的,所以, 我就可以将 la 与 oo 列於 ( ) 当中,并以 | 来分隔开来,就可以啦! egrep -n 'g(la|oo)d' regular_express.txt |
()+ | 意义:多个重复群组的判别 范例:将『AxyzxyzxyzxyzC』用 echo 叫出,然后再使用如下的方法搜寻一下! echo 'AxyzxyzxyzxyzC' | egrep 'A(xyz)+C' 上面的例子意思是说,我要找开头是 A 结尾是 C ,中间有一个以上的 "xyz" 字串的意思~ |
grep -n '[!>]' regular_express.txt
这样可以了解了吗?常常看到有陷阱的题目写:『反向选择这样对否? '[!a-z]'?』, 呵呵!是错的呦~要 '[^a-z] 才是对的!至於更多关於正规表示法的进阶文章,请参考文末的参考数据(
通配符和正则表达式区别
再次强调:正规表示法的特殊字符与一般在shell命令行中的通配符并不相同。
字符 | Shell 通配符含义 | RE正则表达式含义 |
* | 匹配0到任意个字符 | n个前导RE字符 n>=0(组合态) |
. | 无特殊含义 | 任意一个字符 |
? | 1个任意字符 | 0或1个前导RE字符(组合态) |
| | 管道 | 逻辑表达式或 or |
[xyz] | xyz中任意一个字符 | xyz中任意一个字符(和shell通配符含义一样) |
[a-z] [0-9] | a-z 0-9 之间任意一个字符 | 同前 |
[^xyz] [^a-z] | ^取补作用 | 同前 |
{a,b,c} | 大括号变量扩展:{a,b,c}.txt 会被展开为:a.txt b.txt c.txt | 需要转义:\{m,n\} ,具体参照上方描述 |
\ | 转义字符 | 转义字符 |
ls | grep -n '^a.*'
例题: 以 ls -l 配合 grep 找出 /etc/ 底下文件类型为连结档属性的档名 答: 由於 ls -l 列出连结档时标头会是『 lrwxrwxrwx 』,因此使用如下的命令即可找出结果: ls -l /etc | grep '^l' 若仅想要列出几个文件,再以『 |wc -l 』 来累加处理即可。 |
[root@tata.domain /tmp]#ls [0-9]* 1 [root@tata.domain /tmp]#ls [^0-9]* a.txt b.txt c.txt err.log mysqld.sock result.log t.sh [root@tata.domain /tmp]#ls [^a-z]* 1 [root@tata.domain /tmp]#ls [a-z]* a.txt b.txt c.txt err.log mysqld.sock result.log t.sh [root@tata.domain /tmp]#ls [^kpsv]* 1 a.txt b.txt c.txt err.log mysqld.sock result.log t.sh VMwareDnD: [root@tata.domain /tmp]#ls [kp]* keyring-AqbEVb: socket socket.pkcs11 socket.ssh pulse-te4G5RaOCTTo: native pulse-xt8cDgKxvPHQ: [root@tata.domain /tmp]# |
[root@tata.domain ~]#ls |grep '^[li].*' |xargs echo install.log install.log.syslog logon_pro.jsp logon_pro.jsp.1 logon_pro.jsp.2 logon_pro.jsp.3 [root@tata.domain ~]#ls [li]* install.log install.log.syslog logon_pro.jsp logon_pro.jsp.1 logon_pro.jsp.2 logon_pro.jsp.3 [root@tata.domain ~]#
相关文章推荐
- BASH系列(3)―― BASH通配符和正则表达式
- bash通配符 shell正则表达式
- 正则表达式和通配符的区别
- 正则表达式与通配符
- 通配符与正则表达式
- Hadoop 和 spark 读取多个文件通配符规则(正则表达式)joe
- struts2 --- 2.5版本 的正则表达式及通配符的使用
- linux通配符和正则表达式 + notepad++
- linux下的通配符与正则表达式
- 通配符和正则表达式
- 通配符和正则表达式联系和区别
- centos 正则,grep,egrep,流式编辑器 sed,awk -F 多个分隔符 通配符 特殊符号. * + ? 总结 问加星 cat -n nl 输出文件内容并加上行号 alias放~/.bash_profile 2015-4-10 第十三节课
- linux bash shell 正则表达式
- Linux中通配符、正则表达式和扩展正则表达式
- MYSQL-通配符与正则表达式的使用
- bash脚本编程与正则表达式
- 通配符与正则表达式
- MySql like通配符使用(mysql 正则表达式)
- [Elasticsearch] 部分匹配 (二) - 通配符及正则表达式查询
- [Elasticsearch] 部分匹配 (二) - 通配符及正则表达式查询