Bash 类似 echo $pathInVar* 的 glob 扩展
Bash glob expansion like echo $pathInVar*
我有一个包含路径的变量,我想根据该路径扩展一个 glob 模式。我想了解为什么我的尝试不起作用以及在 bash.
中执行此操作的首选方法是什么
EX: 我想列出主目录中的所有文本文件或仅列出以“test”开头的文本文件。我的 失败 次尝试:
foo="~/"
echo $foo*.txt
echo ${foo}test*.txt
这些结果分别导致字符串输出 ~/*
和 ~/test*txt
。我尝试了不同的引号等版本,但我想这足以说明我的问题和理解水平——我是 bash 初学者。该问题与使用 $HOME 的代字号扩展有关吗?
最终,我想遍历这些文件,但我问这个问题是为了理解 bash,而不仅仅是得到结果。
P.S。我确信已经有答案了,但我还没有找到任何帮助我理解这个案例的答案。我试图了解 bash 中的一般扩展顺序,但仍然不明白如何在此处应用它。
在 glob 中,*
匹配文件名中的任何字符,但 不 匹配 /
。因此,要获取主目录中的文件,请尝试:
foo=$HOME
echo $foo/*.txt
echo ${foo}/test*.txt
在 foo
($HOME
) 包含 shell-active 个字符的奇怪情况下,最好使用:
echo "$foo"/*.txt
echo "${foo}"/test*.txt
要遍历此类文件,请使用:
for fname in "$foo"/*.txt
do
# do something
done
此循环结构对所有文件名都是安全的,即使是带有空格或其他 shell-active 字符的文件名。当然,这假设您的循环中的代码在 double-quotes 中适当地包含 $fname
。
修改问题的更新
foo="~/"
~/
在引号内永远不会扩展:
$ foo="~/"
$ echo $foo
~/
如果您真的想使用 ~/
,请不要使用引号。除非您想使用 ~
的奇特功能之一,否则通常使用 $HOME
更简单、更可靠。
如果您的最终目标是列出它们,您可以直接使用
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
我有一个包含路径的变量,我想根据该路径扩展一个 glob 模式。我想了解为什么我的尝试不起作用以及在 bash.
中执行此操作的首选方法是什么EX: 我想列出主目录中的所有文本文件或仅列出以“test”开头的文本文件。我的 失败 次尝试:
foo="~/"
echo $foo*.txt
echo ${foo}test*.txt
这些结果分别导致字符串输出 ~/*
和 ~/test*txt
。我尝试了不同的引号等版本,但我想这足以说明我的问题和理解水平——我是 bash 初学者。该问题与使用 $HOME 的代字号扩展有关吗?
最终,我想遍历这些文件,但我问这个问题是为了理解 bash,而不仅仅是得到结果。
P.S。我确信已经有答案了,但我还没有找到任何帮助我理解这个案例的答案。我试图了解 bash 中的一般扩展顺序,但仍然不明白如何在此处应用它。
在 glob 中,*
匹配文件名中的任何字符,但 不 匹配 /
。因此,要获取主目录中的文件,请尝试:
foo=$HOME
echo $foo/*.txt
echo ${foo}/test*.txt
在 foo
($HOME
) 包含 shell-active 个字符的奇怪情况下,最好使用:
echo "$foo"/*.txt
echo "${foo}"/test*.txt
要遍历此类文件,请使用:
for fname in "$foo"/*.txt
do
# do something
done
此循环结构对所有文件名都是安全的,即使是带有空格或其他 shell-active 字符的文件名。当然,这假设您的循环中的代码在 double-quotes 中适当地包含 $fname
。
修改问题的更新
foo="~/"
~/
在引号内永远不会扩展:
$ foo="~/"
$ echo $foo
~/
如果您真的想使用 ~/
,请不要使用引号。除非您想使用 ~
的奇特功能之一,否则通常使用 $HOME
更简单、更可靠。
如果您的最终目标是列出它们,您可以直接使用
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