没有分词的文件通配?

File globbing without word splitting?

这是一个简化的示例,希望能够说明我的问题。

我有一个脚本需要一个参数作为通配符。有时此通配符包含空格。我需要能够使用通配符进行通配,但分词导致它失败。

例如,考虑以下示例文件:

$ ls -l "/home/me/dir with whitespace"
total 0
-rw-r--r-- 1 me     Domain Users 0 Jun 25 16:58 file_a.txt
-rw-r--r-- 1 me     Domain Users 0 Jun 25 16:58 file_b.txt

我的脚本 - 简化为使用硬编码模式变量 - 如下所示:

#!/bin/bash

# Here this is hard coded, but normally it would be passed via parameter
# For example: pattern=""
# The whitespace and wildcard can appear anywhere in the pattern
pattern="/home/me/dir with whitespace/file_*.txt"

# First attempt: without quoting
ls -l ${pattern}

# Result: word splitting AND globbing
#   ls: cannot access /home/me/dir: No such file or directory
#   ls: cannot access with: No such file or directory
#   ls: cannot access whitespace/file_*.txt: No such file or directory


####################

# Second attempt: with quoting
ls -l "${pattern}"

# Result: no word splitting, no globbing
#   ls: cannot access /home/me/dir with whitespace/file_*.txt: No such file or directory

有没有办法启用 globbing,但禁用分词?
除了手动转义模式中的空格外,我还有其他选择吗?

不要将 glob 保留在引号内以便能够扩展它:

pattern="/home/me/dir with whitespace/file_"

ls -l "${pattern}"*

编辑:

根据已编辑的问题和评论,您可以使用 find:

find . -path "./$pattern" -print0 | xargs -0 ls -l

我终于明白了!

诀窍是将 internal field separator (IFS) 修改为空。这可以防止在 IFS 恢复为旧值或取消设置之前对未引用的变量进行分词。

示例:

$ pattern="/home/me/dir with whitespace/file_*.txt"

$ ls -l $pattern
ls: cannot access /home/me/dir: No such file or directory
ls: cannot access with: No such file or directory
ls: cannot access whitespace/file_*.txt: No such file or directory

$ IFS=""
$ ls -l $pattern
-rw-r--r-- 1 me     Domain Users 0 Jun 26 09:14 /home/me/dir with whitespace/file_a.txt
-rw-r--r-- 1 me     Domain Users 0 Jun 26 09:14 /home/me/dir with whitespace/file_b.txt

$ unset IFS
$ ls -l $pattern
ls: cannot access /home/me/dir: No such file or directory
ls: cannot access with: No such file or directory
ls: cannot access whitespace/file_*.txt: No such file or directory

我发现很难设置和使用 IFSls。例如,这不起作用:

$ IFS="" ls -l $pattern

这是因为命令在IFS变化之前已经进行了分词