我使用的是 FreeBSD,我理解并使用-prune
on 选项find
来防止命令进入子目录。但我发现必要的语法非常笨拙和尴尬。它也不能防止修剪后的目录本身出现,虽然可以修复,但很烦人。
我想创建一个简短的脚本/别名,其作用是-noenter
向find
命令添加新的参数如果它是在任何其他初选之前给出的(为简单起见)。
目的是我可以输入以下任一项:
find -xs /dir -noenter '$*' -name '*.conf' -ls
find -x -s /dir -noenter '$*' -name '*.conf' -ls
它将转换参数并执行:
/usr/bin/find -xs /dir \( -name '$*' -prune -or \( -name '*.conf' -and ! \( -type d -and -name '$*' \) \) \) -ls
/usr/bin/find -x -s /dir \( SNIPPED \) -ls
但我也可以像平常一样输入任何常规的“查找”命令,它会透明地将其传递给/usr//bin/find
执行。
从逻辑上讲,脚本需要识别目录名称后的第一个参数,然后测试它是否:
- ... 等于并且后面至少跟着 2 个参数(在这种情况下,我知道如何通过了解哪些参数在它之前/之后来
-noenter
构建我需要传递的参数);/usr/bin/find
或者 - ... 等于
-noenter
但后面不跟至少 2 个参数(= 错误);或者 - ...任何其他内容或目录是最后一个参数或未找到(= 将整个原始参数传递给
/usr/bin/find
未改变的)。
除了一件事之外,我可以做所有这些 - 我该如何编写脚本来检查 argv 以判断哪个 arg 编号(如果有)是参数dir
?
我选择的 shell 是sh
为了编写脚本。
答案1
如果您想要测试特定参数的存在和位置,您需要做的就是解析命令行并测试每个参数是否与您的“预期”值匹配。因此,您需要测试每个参数的值,-noenter
然后打印一行说明变量的位置和名称-noenter
:
for i in `seq 1 $#`; do
ref=`eval "echo \\$$i"`
if [ $ref == '-noenter' ]; then echo "arg $i is $ref"; break; fi
done
现在同样的事情,只有参数的位置-noenter
存储在中$mitsos
,并且其之前的参数的位置存储在中$mary
:
for i in `seq 1 $#`; do
ref=`eval "echo \\${$i}"`
if [ $ref == '-noenter' ]; then
mitsos=$i
eva=$(($i-1))
mary=`eval "echo \\${$eva}"`
break
fi
done
现在$mitsos
的位置为-noenter
或无值,且$mary
值为 之前的参数-noenter
。此时,如果$mary
具有值,/dir
则知道下一个参数是-noenter
,您可以继续执行find
,否则您将使用系统的版本或打印错误消息。最后,如果您不关心的位置,-noenter
您可以省略行mitsos=$i
。