Bash glob 扩展如 echo $pathInVar*

问题描述 投票:0回答:2

我有一个包含路径的变量,并且想要基于该路径扩展全局模式。我想了解为什么我的尝试不起作用以及在 bash 中执行此操作的首选方法是什么。

EX:我想列出我的主目录中的所有文本文件或仅列出以“test”开头的文本文件。我的失败尝试:

foo="~/"
echo $foo*.txt
echo ${foo}test*.txt

这些结果分别是字符串输出

~/*
~/test*txt
。我尝试过带有引号等的不同版本,但我想这足以表明我的问题和理解水平——我是 bash 初学者。该问题与波浪号扩展与使用 $HOME 有关吗?

最终,我想循环这些文件,但我问这个问题是为了理解 bash,而不仅仅是得到结果。

附注我确信已经有这个问题的答案,但我还没有找到任何可以帮助我理解这个案例的答案。我试图了解 bash 中的一般扩展顺序,但仍然不明白如何在这里应用它。

bash glob expansion
2个回答
4
投票

在 glob 中,

*
匹配文件名中的任何字符,但 匹配
/
。 因此,要获取主目录中的文件,请尝试:

foo=$HOME
echo $foo/*.txt
echo ${foo}/test*.txt

foo
(
$HOME
) 包含 shell 活动字符的奇怪情况下,最好使用:

echo "$foo"/*.txt
echo "${foo}"/test*.txt

要循环访问此类文件,请使用:

for fname in "$foo"/*.txt
do
    # do something
done

此循环结构对于所有文件名都是安全的,即使是带有空格或其他 shell 活动字符的文件名。 当然,这是假设循环中的代码适当地在双引号内包含

$fname

如果没有文件与 glob 匹配,for 循环仍将在与未展开的 glob 匹配的单个项目上运行:

for not_exist in "$foo"/not_exists*.txt; do
    if [[ "$not_exist" == "$foo/not_exists*.txt" ]]; then
        # nothing matched the glob
        break
    fi
done

更新修订后的问题

foo="~/"

~/
在引号内时永远不会扩展:

$ foo="~/"
$ echo $foo
~/

如果您确实想使用

~/
,请不要使用引号。 除非您想使用
~
的奇特功能之一,否则使用
$HOME
通常更简单、更可靠。


1
投票

如果您的最终目标是列出它们,您可以简单地选择

ls "${HOME}"/*.txt # or echo "$HOME"/*.txt

# Output
# /Users/meirgabay/file1.txt      /Users/meirgabay/file2.txt      /Users/meirgabay/some_file.txt

如果您想迭代文件路径,请按以下方法

declare -a _TXT_FILES=()
for file_path in "$HOME"/*.txt; do
    echo "$file_path"
    _TXT_FILES+=("$file_path")
done

echo "${_TXT_FILES[@]}"

# Output
# /Users/meirgabay/file1.txt
# /Users/meirgabay/file2.txt
# /Users/meirgabay/some_file.txt
# /Users/meirgabay/file1.txt /Users/meirgabay/file2.txt /Users/meirgabay/some_file.txt

我使用了一个数组,

declare -a _TXT_FILES=()
,将结果存储在变量中。

如果您想使用

~/
而不是
$HOME
,那也是可以的,只需确保不要用引号括起来即可。
~
字符由 bash 扩展,如果将其放在引号之间,它将被计算为字符串,而不是被扩展。

ls ~/*.txt
/Users/meirgabay/file1.txt      /Users/meirgabay/file2.txt      /Users/meirgabay/some_file.txt

# Output
# /Users/meirgabay/file1.txt      /Users/meirgabay/file2.txt      /Users/meirgabay/some_file.txt

echo ~/*.txt
/Users/meirgabay/file1.txt /Users/meirgabay/file2.txt /Users/meirgabay/some_file.txt

# Output
# /Users/meirgabay/file1.txt /Users/meirgabay/file2.txt /Users/meirgabay/some_file.txt
© www.soinside.com 2019 - 2024. All rights reserved.