經常會遇到一些問題就是為什么命令不是安你想要的執行!!!!舉個例子你
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
轉自:
http://blog.chinaunix.net/u2/76292/showart_1931660.html
posted on 2009-10-05 11:05
chatler 閱讀(218)
評論(0) 編輯 收藏 引用 所屬分類:
Shell