用于循环字符串列表的 Shell 脚本

use*_*326 3 shell sh

下面是我的变量声明,在 shell 脚本中,我正在寻找一种方法来循环字符串列表以获取每个项目。

output='['a.txt', 'b.txt', 'c.txt', 'd.txt']'
Run Code Online (Sandbox Code Playgroud)

我尝试了下面的脚本,但它没有按预期工作

for i in "${output}"; do
    echo $i
   
done
Run Code Online (Sandbox Code Playgroud)

预期结果:

a.txt
b.txt
c.txt
d.txt
Run Code Online (Sandbox Code Playgroud)

tri*_*eee 5

在您的尝试中,引用变量会强制 shell 将其视为单个值。当您需要引用时未能引用是初学者常见的错误,但是当您希望shell 在空格上分割值(并在结果中扩展通配符)时引用也是错误的。也许另请参阅何时将 shell 变量用引号引起来?

只要您的项目只是令牌,您就可以将它们保存在字符串中。

output='a.txt b.txt c.txt d.txt'
for item in $output; do
   echo "$item"  # remember quotes here
done
Run Code Online (Sandbox Code Playgroud)

不过,孤立地看,这个变量不会给你带来任何好处。

for item in a.txt b.txt c.txt d.txt
do
    ...
Run Code Online (Sandbox Code Playgroud)

或者,如果您只想一一打印令牌,只需

printf '%s\n' a.txt b.txt c.txt d.txt
Run Code Online (Sandbox Code Playgroud)

唯一的数据类型sh是字符串。没有简单且安全的方法来存储需要在变量中引用的项目序列。(如果您可以完全控制输入,并且知道自己在做什么,请尝试eval;但通常,这些条件之一或两个都不成立。)

如上所述,如果您可以避免将值保存在变量中,则可以使用您喜欢的任何引用!

for item in "an item" another \
    'yet one more (with "nested quotes" even, see?)'
do
    echo "$item"  # now the quotes are important!
done
Run Code Online (Sandbox Code Playgroud)

Bash 和 Ksh 等都有数组,所以你可以做类似的事情

items=("an item" another 'yet one more (with "nested quotes" even, see?)')
printf '%s\n' "${items[@]}"
Run Code Online (Sandbox Code Playgroud)

但这在 plain 中不可用sh

(无论如何,您也不能按照您尝试的方式嵌套引号。

input='['a.txt', '
Run Code Online (Sandbox Code Playgroud)

[创建一个由(带引号的)紧邻(不带引号的)a.txt紧邻(带引号的)逗号和空格组成的字符串。删除引号后,shell 将简单地将相邻字符串连接成一个字符串。)