Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 设置shell变量以包含文件列表_Bash_Shell - Fatal编程技术网

Bash 设置shell变量以包含文件列表

Bash 设置shell变量以包含文件列表,bash,shell,Bash,Shell,我使用下面的代码来设置一个包含一系列不同文件名的变量,随后我将对这些文件名执行一些函数。所涉及的文件位于与执行代码的目录(当前目录)不同的目录(当前目录)中。我认为可以使用下面的代码更改到包含文件的目录cd$directory,将文件列表存储在变量$files中,然后更改回原始目录(cd$CURRENT\u directory),在那里可以执行其余代码。但是,如果我执行两个echo命令,当我位于文件存储目录中时,第一个命令包含文件列表,但第二个echo命令只打印“vclist\u 2d\u*.t

我使用下面的代码来设置一个包含一系列不同文件名的变量,随后我将对这些文件名执行一些函数。所涉及的文件位于与执行代码的目录(
当前目录
)不同的目录(
当前目录
)中。我认为可以使用下面的代码更改到包含文件的目录
cd$directory
,将文件列表存储在变量
$files
中,然后更改回原始目录(
cd$CURRENT\u directory
),在那里可以执行其余代码。但是,如果我执行两个echo命令,当我位于文件存储目录中时,第一个命令包含文件列表,但第二个echo命令只打印
“vclist\u 2d\u*.txt”
,即它将其解释为字符串而不是文件列表(可能是因为我已更改回原始目录,因此它找不到任何与
vclist\u 2d\u*.txt
匹配的文件)。为什么会发生这种情况,以及如何解决此问题(不在同一目录中运行所有内容)


您需要保存全局扩展的结果

glob不会在简单变量赋值中展开,因此当前代码在
echo
glob时会展开glob(这就是您看到的行为的原因)。例如,尝试
echo“$FILES”
,它根本不会展开


但是,分配给数组时一定要展开,这样
FILES=(vclist_2d_*.txt)
将立即展开全局,然后使用
echo“${FILES[@]}”
以后将正常工作。

您需要保存全局展开的结果

glob不会在简单变量赋值中展开,因此当前代码在
echo
glob时会展开glob(这就是您看到的行为的原因)。例如,尝试
echo“$FILES”
,它根本不会展开


但是,分配给数组时,一定要展开。
FILES=(vclist\u 2d\u*.txt)
将立即展开全局,然后使用
echo“${FILES[@]}”
以后将正常工作。

FILES=vclist\u 2d\u*.txt
不会被shell展开。
FILES
现在包含字符串
vclist\u 2d\u*.txt

echo$FILES
向shell发送
echo vclist_2d_*.txt
。然后shell展开模式,如果模式不匹配,则生成A)字符串
vclist_2d_*.txt
,或者B)匹配文件名的列表

然后更改目录,并重复该过程。分配给任何变量的文件列表都不存在

现在,您可以将
echo vclist\u 2d\u*.txt
的输出分配给一个变量(
SOMEVAR=$(echo vclist\u 2d\u*.txt)
,但这只能解决一半的问题。您打算如何“对列表中的每个文件执行操作”如果您在$SOMEVAR <代码>中考虑文件<代码>,请考虑如果文件名包含空间…

会发生什么? 最简单、最可靠的解决方案是使用
find
代替:

find $DIRECTORY -name "vclist_2d_*.txt" -exec do_something {} +
这会导致
do\u something
传递一个匹配文件列表。如果列表很长,可能会将其拆分为多个调用
do\u something

find $DIRECTORY -name "vclist_2d_*.txt" -exec do_something {} \;
这将导致为每个匹配文件调用
do\u something


如果当前目录可能包含与上面传递给
find
的模式相匹配的文件,则需要转义星号(通过像我一样添加引号,或通过
\*
转义)为了避免shell扩展,请将
find
命令转换为其他命令。

FILES=vclist\u 2d\u*.txt
不会被shell扩展。
FILES
现在包含字符串
vclist\u 2d\u*.txt

echo$FILES
向shell发送
echo vclist_2d_*.txt
。然后shell展开模式,如果模式不匹配,则生成A)字符串
vclist_2d_*.txt
,或者B)匹配文件名的列表

然后更改目录,并重复该过程。分配给任何变量的文件列表都不存在

现在,您可以将
echo vclist\u 2d\u*.txt
的输出分配给一个变量(
SOMEVAR=$(echo vclist\u 2d\u*.txt)
,但这只能解决一半的问题。您打算如何“对列表中的每个文件执行操作”如果您在$SOMEVAR <代码>中考虑文件<代码>,请考虑如果文件名包含空间…

会发生什么? 最简单、最可靠的解决方案是使用
find
代替:

find $DIRECTORY -name "vclist_2d_*.txt" -exec do_something {} +
这会导致
do\u something
传递一个匹配文件列表。如果列表很长,可能会将其拆分为多个调用
do\u something

find $DIRECTORY -name "vclist_2d_*.txt" -exec do_something {} \;
这将导致为每个匹配文件调用
do\u something


如果当前目录可能包含与上面传递给
find
的模式相匹配的文件,则需要转义星号(通过像我一样添加引号,或通过
\*
转义)为了避免shell扩展,将您的
find
命令转换为其他命令。

我本来打算用
FILES=$(echo…
)发布一个答案,但我更喜欢您的数组解决方案。您能解释一下为什么需要
echo“${FILES[@]}”语法吗。这是数组中所有元素的扩展。比如
“$@”
但是对于数组。不幸的是,我在bashref中没有看到关于这一点的好的简明部分(这很奇怪)。我本来打算用
FILES=$(echo…
)发布一个答案,但是我更喜欢你的数组解决方案。你能解释一下为什么
echo“${FILES[@}”
需要语法。这是数组中所有元素的扩展。如
“$@”
但对于数组。Un