这是一个简单的例子,希望能够说明我的问题。
我有一个脚本,它将一个参数用作通配符。有时这个通配符包含空格。我需要能够使用通配符进行通配,但是单词拆分导致它失败。
例如,请考虑以下示例文件:
$ 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
有没有办法启用通配,但禁用单词拆分?
除了手动转义模式中的空格外,我还有其他选择吗?
答案 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 separator(IFS
)修改为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
发生变化之前,该命令已经过分词。