简体   繁体   English

Bash glob 扩展,如 echo $pathInVar*

[英]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

Update for revised question更新修改后的问题

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM