我正在尝试将 .nii 文件 (Gabor3.nii( 路径复制到变量,但即使find
命令找到了该文件,我也无法将路径复制到变量。
find . -type f -name "*.nii"
Data= '/$PWD/"*.nii"'
输出:
./Gabor3.nii
./hello.sh: line 21: /$PWD/"*.nii": No such file or directory
什么问题
您表明您正在使用:
Data= '/$PWD/"*.nii"'
空格表示Data=
部分将环境变量$Data
设置为空字符串,然后尝试运行'/$PWD/"*.nii"'
。 单引号表示它们之间的内容没有展开,并且您没有目录/$PWD
(即根目录中的目录名称$
、P
、W
、D
(,因此在其中找不到脚本"*.nii"
,因此出现错误消息。
使用数组
好吧,这就是问题所在。 什么是对的?
您有几个选择。 最可靠的是使用数组赋值和 shell 扩展:
Data=( "$PWD"/*.nii )
括号(请注意(
前没有空格 - 这是至关重要的(使其成为数组赋值。 使用 shell 通配提供名称列表,正确保留名称中的空格等。 在"$PWD"
两边使用双引号可确保扩展正确,即使当前目录名称中有空格也是如此。
您可以使用以下内容找出列表中有多少个文件:
echo "${#Data[@]}"
您可以使用以下命令循环访问文件名列表:
for file in "${Data[@]}"
do
echo "File is [$file]"
ls -l "$file"
done
请注意,变量引用必须用双引号引起来,带空格的名称才能正常工作。"${Data[@]}"
表示法与"$@"
有相似之处,这也保留了命令参数中的空格。 有一个"${Data[*]}"
变体的行为类似于"$*"
,并且具有类似的有限价值。
如果您担心可能没有任何扩展名的文件,请使用shopt -s nullglob
将通配表达式展开为空列表,而不是历史默认值的未展开表达式。 如有必要,您可以使用shopt -u nullglob
取消设置该选项。
选择
替代方案涉及诸如使用命令替换Data=$(ls "$PWD"/*.nii)
之类的事情,但这远远不如使用数组,除非$PWD
中的路径和文件名都不包含任何空格、制表符、换行符。 如果名称中没有空格,则工作正常;您可以迭代:
for file in $Data
do
echo "No white space [$file]"
ls -l "$file"
done
但是,如果周围有任何(或可能有(任何空白字符,这完全不那么令人满意。
您可以使用命令替换:
Data=$(find . -type f -name "*.nii" -print -quit)
为了防止多行输出,-quit
选项在找到第一个文件后停止搜索(除非您确定只找到一个文件或想要处理多个文件(。
执行您似乎正在尝试执行的操作的语法:
Data= '/$PWD/"*.nii"'
将:
Data="$(ls "$PWD"/*.nii)"
当然,并不是说这是你接下来想做的任何事情的最佳方法,它可能不是......