在 for 循环中回显列出与输出模式匹配的文件

echo inside a for loop lists files matching the output pattern

我对以下 for 循环有疑问:

X="*back* OLD"
for P in $X
do
echo "-$P"
done

我只需要它输出:

-*back*
-OLD

但是,它会列出当前目录中与 *back* 模式匹配的所有文件。例如,它给出以下内容:

-backup.bkp
-backup_new.bkp
-backup_X
-OLD

如何强制输出准确的模式?

使用数组,因为不带引号的参数扩展仍然会出现通配。

 X=( "*back*" OLD )
 for P in "${X[@]}"; do
     printf '%s\n' "$P"
 done

(使用 printf,因为 echo 可能会尝试将参数解释为一个选项,例如,如果 X 的值中包含 n。 )

防止filename expansion you could read in the string as a Here String.

要遍历项目,您可以使用 parameter expansion 将它们变成行,然后使用 read 逐行读取它们。为了能够将 - 符号作为第一个字符,请使用 printf 而不是 echo

X="*back* OLD"
while read -r x
do printf -- '-%s\n' "$x"
done <<< "${X/ /$'\n'}"

另一种方法是使用 tr 将字符串转换为行,然后使用 paste- 符号作为分隔符,并使用 /dev/null 中的“无”作为第一列。

X="*back* OLD"
tr ' ' '\n' <<< "$X" | paste -d- /dev/null -

两者都应该输出:

-*back*
-OLD

在循环之前使用 set -o noglob 并在循环之后使用 set +o noglob 来禁用和启用 globbing。