2014-04-29 50 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