Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4824298
  • 博文数量: 930
  • 博客积分: 12070
  • 博客等级: 上将
  • 技术积分: 11448
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-15 16:57
文章分类

全部博文(930)

文章存档

2011年(60)

2010年(220)

2009年(371)

2008年(279)

分类:

2009-05-17 12:20:08

  经常会遇到一些问题就是为什么命令不是安你想要的执行!!!!举个例子你
  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



阅读(2063) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~