2016-12-14 54 views
3

在bash shell中,我想列出具有完整路径的$文件夹(在我的代码中的变量名称)下的文件名。字符串连接作为命令的参数

但是,如果我像这样的代码,

dir $folder"*" 

它输出错误

"dir: cannot access <folder_name> : No such file or directory" 

如果我改变这样的代码它的工作原理,

search_str=$folder"*" 
dir $search_str 

看来,连接到dir命令的字符串不是我想要的,如果我将该字符串存储在一个变量中并仅将其传递给dir命令 有用。

任何人都知道原因&如何不使用search_str?

回答

0

假设$文件夹是TMP然后 DIR $文件夹中有 “*” 的下面

search_str=$folder"*" 
dir $search_str 

$ SEARCH_STR相当于dir temp

当你使用的情况下,同时就相当于dir tmp*

双引号,它需要一个额外的步骤来扩大。查看更多变扩建壳

5

注:我使用的是标准的Unix工具ls,而不是GNU-specific utility dir(感谢,hek2mgl)在下面的例子中,由于问题涉及到通用的外壳行为,并不仅限于与平台GNU实用程序。

TL;博士

ls "$folder"* # double-quote the var. reference, use * unquoted 

模式(通配符)元字符如*必须使用无引号才能被识别。

因此,ls $folder"*"都会不约而同工作如预期,因为你(双)引述*

相比之下,可变分配search_str=$folder"*"使*要附加到的$folder值(作为字面,因为它是双引号,但最终没有引号,因为外壳的过程中除去了双引号由于它们具有句法含义而不是文字;这种去除适当地称为报价去除)。

它是在命令ls $search_str变量的加引号使用其然后使*有效作为通配符(图案元字符)。

然而,这不带引号的使用可变的固有不稳健,因为$search_str整体不仅受到通配符,也字分裂,这意味着如果原始$folder变量包含一个带有嵌入空间的路径,该命令将会中断。

因此最好是需求,追加*通配符实际上是在需要的时候:

ls "$folder"* 

注意如何*是未加引号的 - 让它有效的模式元字符 - 而"$folder"是故意双引号 - 确保使用原样(字词拆分和通配不适用于其值)。

+1

好答案!如果你喜欢,我发现[这](http://askubuntu.com/a/615946/217021)一个有趣的阅读。 – hek2mgl

+0

@ hek2mgl:我欣赏指针 - 我不知道dir是否存在:)答案已更新。 – mklement0

0

虽然@ mklement0的回答解释了错误的原因,但您也可以寻找可能的其他解决方案。首先让我从对方的回答借用低于线

模式(通配符)元字符,例如*必须 顺序使用不带引号的被承认。

案例1:如果您希望列出(不解析,只是列表)的文件(文件只)递归文件夹内,
使用[ globstar ]

shopt -s globstar 
folder="yourfoldername**" 
ls -p $folder | grep -v '/$' #mind that '$folder' is not inside double quotes 
# '-p' adds trailing slash to directories and we neglect those results using grep invert match 
# Here I inadvertantly parsed the `ls` output, see the link in case 2 for why you shouldn't do that. 

案例2:如果你想解析(不只是列表)的文件(文件只)递归的文件夹内,使用find作为ls输出不能被解析。 [Check this]

folder="yourfoldername" #no trailing ** 
find "$folder" -type f -print0 | while read -r -d '' fname 
do 
#do something with "$fname" 
done 
+1

你正在用'grep'有效地解析'ls'的输出;任何包含换行符的文件名都会被grep看成两行。 – chepner

+0

@chepner:哎呀,我无意中做了..我已经添加了一个关于这个:)的说明 – sjsam

相关问题