[英]Bash glob expansion like echo $pathInVar*
I have a variable containing a path and want to expand a glob pattern based on that path.我有一个包含路径的变量,并想根据该路径扩展一个 glob 模式。 I want to understand why my attempts don't work and what is the preferred way of doing this in bash.
我想了解为什么我的尝试不起作用以及在 bash 中执行此操作的首选方法是什么。
EX : I want to list all text files in my home directory or only those that starts with "test".例如:我想列出我的主目录中的所有文本文件,或者只列出以“test”开头的那些文本文件。 My failing attempts:
我失败的尝试:
foo="~/"
echo $foo*.txt
echo ${foo}test*.txt
These results in the string outputs ~/*
and ~/test*txt
respectively.这些结果分别在字符串输出
~/*
和~/test*txt
。 I have tried different versions with quotes etc. but I guess this enough to show my issue and level of understanding — I am a bash beginner.我已经尝试了不同版本的引号等。但我想这足以表明我的问题和理解水平——我是一个 bash 初学者。 Is the issue related to tilde expansion vs. using $HOME?
问题是否与波浪号扩展与使用 $HOME 相关?
Ultimately, I want to loop over these files but I ask this question to understand bash, not just get the result.最终,我想遍历这些文件,但我问这个问题是为了理解 bash,而不仅仅是得到结果。
PS I am certain there are answers to this already out there but I've not managed to find any that have helped me understand this case. PS我确信已经有答案了,但我还没有找到任何帮助我理解这个案例的答案。 I tried to understand the general expansion order in bash but still don't understand how to apply it here.
我试图了解 bash 中的一般扩展顺序,但仍然不明白如何在此处应用它。
In a glob, *
matches any character in a file name but it does not match /
.在 glob 中,
*
匹配文件名中的任何字符,但不匹配/
。 Thus, to get files in your home directory, try:因此,要获取主目录中的文件,请尝试:
foo=$HOME
echo $foo/*.txt
echo ${foo}/test*.txt
In the odd case that foo
( $HOME
) includes shell-active characters, it is better practice to use:在
foo
( $HOME
) 包含 shell-active 字符的奇怪情况下,更好的做法是使用:
echo "$foo"/*.txt
echo "${foo}"/test*.txt
To loop over such files, use:要循环这些文件,请使用:
for fname in "$foo"/*.txt
do
# do something
done
This loop structure is safe for all filenames, even ones with spaces or other shell-active characters.这种循环结构对于所有文件名都是安全的,即使是带有空格或其他 shell 活动字符的文件名。 This, of course, assumes that the code in your loop has
$fname
inside double-quotes as appropriate.当然,这假设循环中的代码在适当的情况下在双引号内包含
$fname
。
foo="~/"
~/
never expands when inside quotes: ~/
在引号内时永远不会扩展:
$ foo="~/"
$ echo $foo
~/
If you really want to use ~/
, don't use quotes.如果您真的想使用
~/
,请不要使用引号。 Unless you want to use one of the fancy features of ~
, it is usually simpler and more reliable to use $HOME
instead.除非您想使用
~
的奇特功能之一,否则使用$HOME
通常更简单、更可靠。
If your end goal is to list them, you can simply go with如果您的最终目标是列出它们,您可以简单地使用
ls "${HOME}"/*.txt # or echo "$HOME"/*.txt
# Output
# /Users/meirgabay/file1.txt /Users/meirgabay/file2.txt /Users/meirgabay/some_file.txt
If you want to iterate over files paths, here's how如果你想遍历文件路径,这里是如何
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
I used an array, declare -a _TXT_FILES=()
, to store the results in a variable.我使用了一个数组
declare -a _TXT_FILES=()
将结果存储在一个变量中。
If you want to use ~/
instead of $HOME
, that's also possible, just make sure you don't surround it with quotes.如果您想使用
~/
而不是$HOME
,这也是可能的,只需确保不要用引号将其括起来。 The ~
character is expanded by bash, and if you put it between quotes, it is evaluated as a string, instead of getting expanded. ~
字符由 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.