我正在尝试解析映射驱动器上目录中的一组文件。但是,我似乎无法解决似乎由于子目录路径中的空格而导致的问题。将不胜感激任何帮助!谢谢。
#!/bin/bash
FILES=/home/user/.gvfs/analysis\$\ on\ server.university.edu/users/username/m/BED_files/*
#FILES=/home/user/Desktop #this works
for f in "${FILES}"
do
echo $f
done
答案1
如果您还使用引号,则不能将通配符用作变量的一部分。请注意,在 @jasonwryan 建议的数组变量语法中,它是在初始化数组时查看目录的内容,而不是在执行循环时查看目录的内容。
#!/bin/sh
DIR='/home/user/.gvfs/analysis$ on server.university.edu/users/username/m/BED_files'
for f in "$DIR"/*
do
echo "$f"
done
如果您确实需要在变量中定义通配符,请将其放在单独的变量中即可:
#!/bin/sh
DIR='/home/user/.gvfs/analysis$ on server.university.edu/users/username/m/BED_files'
FILES='*.txt'
for f in "$DIR"/$FILES
do
echo "$f"
done
答案2
验证您是否具有一直到最终子目录的权限,并且 @jasonwryan 答案应该有效。
答案3
如果您想在基本 POSIX shell 中使用数组扩展结果,则必须注意$IFS
文件名生成。您可以安全地使用不带引号的变量 - 但这通常不是最简单的方法。
Shell 的设计首先是为了与论点- 所以我建议你使用参数数组:
set -- "${FILES%/*}"/*
不过,您必须检查 glob 的结果 - 在任何 POSIX shell 中,如果 glob 无法解析,它仍将保留为可迭代参数。这for var in glob*
也是如此 - 如果不测试结果,您就无法确定您实际上正在使用文件。所以...
for f do [ -e "$f" ] || [ -L "$f" ] && printf %s\\n "$f"; done
您可以像这样迭代 arg 数组中的项目for arg do ...;done
。您还可以在循环内将它们寻址为"$1"
"$2
" 等,或者将它们作为一个整体使用"$@"
和之一进行寻址"$*"
。当循环完成时,数组保持设置状态。
最后要注意的是,正如我之前提到的,文件名生成是 shell 的一项可配置功能。可以使用 禁用它set -f
或使用 启用它set +f
。更重要的是,它仅在您搜索的目录中存在匹配的文件名时才有效 - 如果没有,您只需找回未解析的 glob。全局匹配还需要目录的搜索和执行权限。因此,如果您发现无法解析全局匹配,您可以尝试启用文件名生成,检查路径的权限,并首先验证那里是否有文件。