我使用以下代码来设置包含一系列不同文件名的变量,然后我将执行一些函数。涉及的文件位于执行代码的目录(DIRECTORY
)的不同目录(CURRENT_DIRECTORY
)中。我认为可以使用以下代码更改为包含文件cd $DIRECTORY
的目录,将文件列表存储在变量$FILES
中,然后更改回原始目录(cd $CURRENT_DIRECTORY
)其余代码可以执行的地方。但是,如果我执行两个echo命令,第一个包含文件列表,当我在存储文件的目录中时,第二个echo命令只打印'vclist_2d_*.txt'
,即它将此解释为字符串而不是文件列表(可能是因为我已经更改回原始目录,因此无法找到与vclist_2d_*.txt
匹配的任何文件)。为什么会发生这种情况,如何解决这个问题(不在同一目录中运行所有内容)?
#!/bin/bash
CURRENT_DIRECTORY=`pwd`
DIRECTORY=/home/Documents/NewDirectory/
cd $DIRECTORY
pwd
FILES=vclist_2d_*.txt
echo $FILES
cd $CURRENT_DIRECTORY
echo $FILES
答案 0 :(得分:4)
您需要保存glob扩展的结果。
Glob不会在简单的变量赋值中展开,因此当前代码在echo
时扩展了glob(这就是为什么你会得到你所看到的行为)。请尝试echo "$FILES"
,例如,它根本不会扩展。
然后,对数组的赋值进行扩展,以便FILES=(vclist_2d_*.txt)
立即扩展glob,然后使用echo "${FILES[@]}"
将正常工作。
答案 1 :(得分:1)
FILES=vclist_2d_*.txt
。 FILES
现在包含字符串vclist_2d_*.txt
。
echo $FILES
将echo vclist_2d_*.txt
发送到shell。然后shell扩展模式,如果模式不匹配,则导致A)字符串vclist_2d_*.txt
,或者B)匹配文件名列表。
然后更改目录,并重复此过程。在任何时候都不是分配给任何变量的文件列表。
现在,您可以将echo vclist_2d_*.txt
的输出分配给变量(SOMEVAR=$(echo vclist_2d_*.txt)
,但这只会解决您的问题的一半。你打算“对列表中的每个文件采取行动吗?”如果你正在考虑for file in $SOMEVAR
,请考虑如果文件名包含空格会发生什么......
最简单,最强大的解决方案是改为使用find
:
find $DIRECTORY -name "vclist_2d_*.txt" -exec do_something {} +
这导致do_something
传递了匹配文件列表。如果列表非常长,则可能会将其拆分为do_something
的多个调用。
find $DIRECTORY -name "vclist_2d_*.txt" -exec do_something {} \;
这会导致为每个匹配的文件调用do_something
。
如果您的当前目录可能包含与上面传递给find
的模式匹配的文件,则需要转义星号(通过添加我所做的引号或转义)它通过\*
)来避免shell扩展将你的find
命令转换为其他命令。