Chinaunix首页 | 论坛 | 博客
  • 博客访问: 593573
  • 博文数量: 226
  • 博客积分: 10080
  • 博客等级: 上将
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2007-11-26 11:15
文章分类

全部博文(226)

文章存档

2011年(5)

2010年(64)

2009年(99)

2008年(37)

2007年(21)

我的朋友

分类: LINUX

2009-12-27 10:41:03

经常会遇到一些问题就是为什么命令不是安你想要的执行!!!!举个例子你
find /usr -type f -name string*
你本意你想找string.c .h阿.什么之类的.就是*是当通配符了.可是如果你的当前路径有个string.c文件的话,你就知道问题了。

[root@mip-123456 string]# ls
[root@mip-123456 string]# find /usr/src/linux-2.6.18/arch/ -type f -name string*
/usr/src/linux-2.6.18/arch/ppc/lib/string.S
/usr/src/linux-2.6.18/arch/ppc/boot/common/string.S
/usr/src/linux-2.6.18/arch/m68k/lib/string.c
/usr/src/linux-2.6.18/arch/cris/arch-v10/lib/string.c
/usr/src/linux-2.6.18/arch/cris/arch-v32/lib/string.c
/usr/src/linux-2.6.18/arch/s390/lib/string.c
/usr/src/linux-2.6.18/arch/powerpc/lib/string.S
/usr/src/linux-2.6.18/arch/powerpc/boot/string.h
/usr/src/linux-2.6.18/arch/powerpc/boot/string.S
[root@mip-123456 string]# touch string.h
[root@mip-123456 string]# find /usr/src/linux-2.6.18/arch/ -type f -name string*
/usr/src/linux-2.6.18/arch/powerpc/boot/string.h
[root@mip-123456 string]# find /usr/src/linux-2.6.18/arch/ -type f -name "string*"
/usr/src/linux-2.6.18/arch/ppc/lib/string.S
/usr/src/linux-2.6.18/arch/ppc/boot/common/string.S
/usr/src/linux-2.6.18/arch/m68k/lib/string.c
/usr/src/linux-2.6.18/arch/cris/arch-v10/lib/string.c
/usr/src/linux-2.6.18/arch/cris/arch-v32/lib/string.c
/usr/src/linux-2.6.18/arch/s390/lib/string.c
/usr/src/linux-2.6.18/arch/powerpc/lib/string.S
/usr/src/linux-2.6.18/arch/powerpc/boot/string.h
/usr/src/linux-2.6.18/arch/powerpc/boot/string.S
聪明的你已经看出问题了。

由于[0-9]这种匹配模式是出现在命令的 argument位置上,所以由shell负责解释(所以严格而言, [0-9]是通配符,而不是正则表达式)。对shell而言,统配符只对文件名有效,也就是说,当shell遇到出现在某个命令行的argument位置 上的通配符时,它先要去参数所指定的目录下搜索所有已经存在的文件,所有文件名字与之匹配的都要替换到argument位置上(这与很多标准的命令支持多 个文件名参数是一致的),然后调用该命令执行.

对于mkdir ./dir[0-9]而言,shell无法在当前目录下找到与之匹配的文件名,所以就不替换,dir[0-9]按照原样传给mkdir程序,所以mkdir就建立了一个名字为dir[0-9]的目录.

总之一句话,通配符(出现在argument位置)由shell负责解释(与现有的文件名匹配),与具体的命令(ls,rm,mkdir)无关.正则表达式(出现在option位置上)由具体的应用程序解释(grep,sed,awk),与shell无关。

一个试验的例子是:
如果当前目录下已经有一个名为dir5的目录,执行 mkdir ./dir[0-9]后,出现错误提示:mkdir: cannot create directory `./dir5': File exists 这就证明了,因为存在dir5,所以shell匹配到了dir5,所以真正执行的是mkdir ./dir5

seq -f 'dir%01g' 0 9 | xargs mkdir
[victor@localhost tmp]$ ls
[victor@localhost tmp]$ seq -f 'dir%01g' 0 9 | xargs mkdir
[victor@localhost tmp]$ ls
dir0 dir1 dir2 dir3 dir4 dir5 dir6 dir7 dir8 dir9

seq 是Linux 中一個預設的外部命令,一般用作一堆數字的簡化寫法,如
seq 1 10
便會出現
1
2
3
4
5
6
7
8
9
10
它還有三個選項
-f, --format=FORMAT use printf style floating-point FORMAT (default: %g)
-s, --separator=STRING use STRING to separate numbers (default: \n)
-w, --equal-width equalize width by padding with leading zeroes
-f 最常用 , 例如一次制做 10 個名 dir001 , dir002 .. dir010 的目錄,它便很有用途,我們可以這樣
下一個命令便可了
seq -f 'dir%03g' 1 10 | xargs mkdir

mkdir $(seq -f 'dir%03g' 1 10)
它用的是 printf 的格式 , %03g' 代表以三位浮點數,以此方法,
如用bash3 的 printf也可作為等價命令
printf 'dir%03d\n' {1..10} | xargs mkdir 或 mkdir `printf 'dir%03d ' {1..10}`
awk 當然也可以
awk 'BEGIN { while (num < 10 ) printf "dir%03d\n", ++num ; exit}' | xargs mkdir
這樣會比寫一個腳本快, 不必寫成
for dir in 001 002 003 004 005 006 007 008 009 010
do
mkdir dir${dir}
done
阅读(603) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~