文件通配没有分词?

时间:2015-06-25 22:17:10

标签: bash shell glob

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

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

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

$ 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="${1}"
# 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

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

2 个答案:

答案 0 :(得分:3)

不要在报价中保留glob以便能够扩展它:

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

ls -l "${pattern}"*

修改

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

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

答案 1 :(得分:0)

我终于明白了!

诀窍是将internal field separatorIFS)修改为null。这可以防止对未加引号的变量进行单词拆分,直到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

我发现您无法使用IFS设置和使用ls。例如,这不起作用:

$ IFS="" ls -l $pattern

这是因为在 IFS发生变化之前,该命令已经过分词。