Bash 函数参数中的通配符问题
Issue with wildcards into arguments of a Bash function
从下面link,我尝试用下面的方案比较了一组源文件(这里是fortran90 = *.f90)
为了做到这一点和查看源码有什么不同,我已经放入我的 ~/.bashrc :
function diffm { for file in ""/""; do diff -qs "$file" ""/"${file##*/}"; done ;}
但不幸的是,如果我在参数 </code> 的当前目录中,即执行:</p>
<pre><code>$ diffm . '*.f90' ../../dir2
结果是:impossible to access to './*.f90'
。但是,来源 *.f90
存在,但不考虑通配符。
肯定是我函数参数上的双引号问题 (</code>、<code>
、</code>)?</p>
<p>更一般地说,此功能效果不佳。</p>
<p>如何修改此函数以使其在所有情况下都能正常工作,即使在当前目录“<code>.
”中第一个参数 </code> 或第三个 <code>
?
如果我明白你想做什么,这应该行得通
diffm () {
dir=""; shift
for file in "$@"; do
filename=$(basename "$file")
diff -qs "$file" "$dir/$filename"
done
}
用法
diffm ../../dir2 ./*.f90
文件名生成不在引号内。因此,您将文字字符串 *.f90
传递给函数,并且该字符串也按字面意义在那里使用。如果您确定您的目录中只有一个 f90 文件,请不要使用引号并写
diffm . *.f90 ../../dir2
如果文件名嵌入了 space,事情就会变得很难看(顺便说一句,这是我更喜欢 Zsh 而不是 bash 的原因之一——在 Zsh 中你不必关心这个).要处理这种情况,您可以执行
myfile=*.f90
diffm . "$myfile" ../../dir2
但迟早,您会被这样一个事实所困扰,即无论出于何种原因,您拥有多个 f90 文件,并且您的策略将会失败。因此,更好的解决方案是使用循环,这也适用于只有一个文件的边界情况:
iterating=0
for myfile in *.f90
do
if ((iterating == 0))
then
((iterating+=1))
diffm . "$myfile" ../../dir2
elif [[ ! -f $myfile ]]
then
echo "No files matching $myfile in this directory"
else
echo "ERROR: More than one f90-file. Don't know which one to diff" 1>&2
fi
done
elif
部分只关心您没有任何 f90 文件的情况。在这种情况下,循环体被执行一次,myfile
包含通配符模式。
从下面link,我尝试用下面的方案比较了一组源文件(这里是fortran90 = *.f90)
为了做到这一点和查看源码有什么不同,我已经放入我的 ~/.bashrc :
function diffm { for file in ""/""; do diff -qs "$file" ""/"${file##*/}"; done ;}
但不幸的是,如果我在参数 </code> 的当前目录中,即执行:</p>
<pre><code>$ diffm . '*.f90' ../../dir2
结果是:impossible to access to './*.f90'
。但是,来源 *.f90
存在,但不考虑通配符。
肯定是我函数参数上的双引号问题 (</code>、<code>
、</code>)?</p>
<p>更一般地说,此功能效果不佳。</p>
<p>如何修改此函数以使其在所有情况下都能正常工作,即使在当前目录“<code>.
”中第一个参数 </code> 或第三个 <code>
?
如果我明白你想做什么,这应该行得通
diffm () {
dir=""; shift
for file in "$@"; do
filename=$(basename "$file")
diff -qs "$file" "$dir/$filename"
done
}
用法
diffm ../../dir2 ./*.f90
文件名生成不在引号内。因此,您将文字字符串 *.f90
传递给函数,并且该字符串也按字面意义在那里使用。如果您确定您的目录中只有一个 f90 文件,请不要使用引号并写
diffm . *.f90 ../../dir2
如果文件名嵌入了 space,事情就会变得很难看(顺便说一句,这是我更喜欢 Zsh 而不是 bash 的原因之一——在 Zsh 中你不必关心这个).要处理这种情况,您可以执行
myfile=*.f90
diffm . "$myfile" ../../dir2
但迟早,您会被这样一个事实所困扰,即无论出于何种原因,您拥有多个 f90 文件,并且您的策略将会失败。因此,更好的解决方案是使用循环,这也适用于只有一个文件的边界情况:
iterating=0
for myfile in *.f90
do
if ((iterating == 0))
then
((iterating+=1))
diffm . "$myfile" ../../dir2
elif [[ ! -f $myfile ]]
then
echo "No files matching $myfile in this directory"
else
echo "ERROR: More than one f90-file. Don't know which one to diff" 1>&2
fi
done
elif
部分只关心您没有任何 f90 文件的情况。在这种情况下,循环体被执行一次,myfile
包含通配符模式。