2014-04-29 49 views
1

我在讀下面的教程擴展在Linux中

http://linuxcommand.org/lc3_lts0080.php

它說,關於雙引號:

雙引號

第一種類型的報價,我們將看看是雙引號。 如果您將文本置於雙引號內,則shell 使用的所有特殊字符將失去其特殊含義並被視爲普通字符。例外是「$」, 「\」(反斜槓)和「`」(反引號)。這意味着字分割,路徑名擴展,波形擴展和大括號擴展被抑制,但是仍然執行參數擴展, 算術擴展和命令替換。

而關於單引號:

單引號

如果需要抑制所有的擴展,可以使用單引號。

它說明,與ls爲什麼只有*.txt工作不"*.txt"'*.txt'

$ ls -l *.txt 
-rw-r--r-- 1 Gaurav None 8893 Apr 17 06:25 BigText.txt 
-rwxr-xr-x 1 Gaurav None 54376 Apr 18 12:32 File.txt 
-rw-r--r-- 1 Gaurav None 371 Apr 23 21:04 Filelist.txt 
-rwxr-xr-x 1 Gaurav None 54386 Apr 18 12:28 FileOld.txt 
-rw-r--r-- 1 Gaurav None 1163 Apr 17 06:19 Read.txt 
-rw-r--r-- 1 Gaurav None 651 Apr 24 06:28 temp.txt 


$ ls -l "*.txt" 
ls: cannot access *.txt: No such file or directory 
$ ls -l '*.txt' 
ls: cannot access *.txt: No such file or directory 

我的問題是,隨着find or grep爲什麼"*.txt", '*.txt'都提供了擴展:(其實*.txt沒有提供任何擴展爲名稱而不是ls

eg

$ find . -name *.txt 
find: paths must precede expression: File.txt 
Usage: find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression] 


$ find . -name "*.txt" 
./BigText.txt 
./File.txt 
./Filelist.txt 
./FileOld.txt 
./Read.txt 
./sample/BigText.txt 
./sample/File.txt 
./sample/FileOld.txt 
./sample/Read.txt 
./sample/temp.txt 
./temp.txt 


$ find . -name '*.txt' 
./BigText.txt 
./File.txt 
./Filelist.txt 
./FileOld.txt 
./Read.txt 
./sample/BigText.txt 
./sample/File.txt 
./sample/FileOld.txt 
./sample/Read.txt 
./sample/temp.txt 
./temp.txt 
+1

根據您的輸出,擴展由shell正確處理。 '*'在雙引號內失去意義,因此當作爲參數傳遞給任何命令時,將不會被擴展。 'find'在'-name'之後需要'pattern',因此需要使用quote或shell會擴展表達式並導致語法錯誤。 – alvits

回答

3

find做了自己的* –的擴張不需要shell來做到這一點。

你需要知道的,當你在shell命令(或當外殼從腳本執行命令)會發生什麼:

首先,所有的擴展被shell做,例如可變擴展(將$foo轉換爲foo的值),波形擴展(將~轉換爲主目錄路徑)和通配符(將*轉換爲所有匹配的文件)。

然後,在所有擴展完成後,擴展值作爲命令執行。

當你調用find,你實際做希望shell擴展你傳遞給find作爲模式的一部分*,因爲find命令本身解釋*並使用它作爲一個搜索模式(如在find <dir> -name '*.foo'中)。

+0

'find'在'-name'作爲'regex'後使用參數。在'-name'之後讓shell擴展參數會導致語法錯誤。 – alvits

+2

是的,這就是爲什麼我寫道,當你使用find的時候,你確實想保護shell中的'*'。順便說一句,我認爲你錯了正則表達式。 '-name'確實需要一個shell glob,而不是一個正則表達式。 – Sigi

+2

我剛剛檢查了'find'的手冊頁:'-name'不採用正則表達式。如果你想這樣做,你必須使用'-regex' – Sigi

1

ls的情況下,shell擴展通配符併爲該命令提供多個參數。

ls *.txt -> ls a.txt b.txt c.txt 

find的情況下,通配符被傳遞到命令本身和它負責在-{,i}name的情況下擴大他們,glob(3)

1

ls依賴於shell擴展,這意味着shell本身,當它看到*.txt時,將其替換爲當前目錄中所有匹配文件的列表。使用引號可以抑制shell擴展。

您可以使用echo查看殼體擴展。嘗試:

echo '*.txt' 
echo "*.txt" 
echo *.txt