bash脚本为';设置参数时出现问题;查找';效用

bash脚本为';设置参数时出现问题;查找';效用,bash,find,wildcard,Bash,Find,Wildcard,这里的基本问题是,我想使用一个脚本来简化使“find”实用程序跳过某个麻烦的目录 Bash脚本不是我的强项套件。我一直在研究如何将命令行中引用的通配符文件规范导入脚本,并从脚本中导入一个完整的find命令。看起来bash喜欢从引用中删除内容,并将包含通配符的单词扩展到单词列表中,这通常是很好的,但是当我尝试在脚本中计算“find”时,这种命令行烹饪会发生两次,结果不理想 现在,我将给出血淋淋的细节,b/c也许有人会看到我真正想做的事情,并说‘嘿,你知道有一个更简单的方法来做这件事’。绕着这个问题

这里的基本问题是,我想使用一个脚本来简化使“find”实用程序跳过某个麻烦的目录

Bash脚本不是我的强项套件。我一直在研究如何将命令行中引用的通配符文件规范导入脚本,并从脚本中导入一个完整的find命令。看起来bash喜欢从引用中删除内容,并将包含通配符的单词扩展到单词列表中,这通常是很好的,但是当我尝试在脚本中计算“find”时,这种命令行烹饪会发生两次,结果不理想

现在,我将给出血淋淋的细节,b/c也许有人会看到我真正想做的事情,并说‘嘿,你知道有一个更简单的方法来做这件事’。绕着这个问题跑一圈对我来说没问题

那么背景呢,-

在所讨论的机器上,有一个自动备份系统,它可以归档某些目录的大约24个快照,例如用户的主目录和各种项目位置。因此,在我的主目录中,我有~/.backup/hourly.0、~/.backup/hourly.1等,从大约每小时的.12开始,然后是每夜的.1到大约每夜的.12,所以有大量的重复。通常这是一个很好的安全网,直到我想在我的主目录中“找到”一些东西

例如,假设我想找到所有的*.foo文件;简单的解决办法是发行股票

find ~ -name "*.foo"
。。除了在这台机器上,find开始筛选所有这些备份目录。通常我对.backup目录不感兴趣。搜索它们的速度很慢,据我所知,它们是网络挂载的,我正在融化某人的数据柜。所以下一个进化就是用这样的形式做一些事情

find ~ ! \( -name .backup -prune \) -a -name "*.foo"
find $1 ! \( -name .backup -prune \) $2 $3 $4 $5 $6 $7
。。这很有效,如果只需要使用一两次也不算太糟糕。但它很容易胖手指,当连续几次需要它时,它会变得烦人。所以写一个脚本来处理这个问题似乎是个好主意。由于缺少更具想象力的名称,让我们使用“findx”。其想法是发布findx~-名称“*.foo”,并让“findx”自动将其转换为更复杂的形式。对脚本的第一次破解是这样的

find ~ ! \( -name .backup -prune \) -a -name "*.foo"
find $1 ! \( -name .backup -prune \) $2 $3 $4 $5 $6 $7
诚然,这看起来非常笨拙,对于参数太多的搜索不起作用。(如果有办法指定‘从第二个参数开始的所有参数’,我不知道。)find命令的特殊语法似乎指示从其余参数中拆分$1,b/c搜索根位置必须先到,-prune和-print子句如果顺序相反,则不能正确工作,所以-prune必须在(隐式)打印的东西之前出现,在右边留下2美元3美元等。无论如何,对于足够简单的搜索来说,它应该已经足够了

好吧,对于特定的文件名来说,这似乎是可行的,但是通配符使它失效了。比如说,如果我喂它

findx . -name "*stuff"
bash首先去掉了*的引号,然后将其作为$param之一传递到脚本中。然后生成的find命令没有括住通配符的引号;因此,当它被执行时,shell会在执行find之前展开*然后阻塞,b/c find想要的是一个单词*的内容,而不是它展开到的列表。(显然find喜欢自己进行通配符扩展?)


那么,有没有办法让它发挥作用?有没有其他方法可以省去搜索一个不那么冗长的目录,从而消除编写脚本的动机?查找的另一种方法,它可以完成查找的大部分功能,例如,-ctime,-type,-name,等等?

这不是一个完整的答案,但看看thd,我看到了一些有趣的事情

$@

与$*相同,但每个参数都是带引号的字符串,也就是说,参数是完整传递的,没有解释或扩展。这意味着,除其他外,参数列表中的每个参数都被视为一个单独的单词

这对于通配符扩展问题可能很有用

移位后,$@保留其余的命令行参数,缺少先前丢失的$1

这是一种从第二个参数开始指定所有参数的方法


我希望这能有所帮助。

这不是一个完整的答案,但看看thd,我看到了一些有趣的事情

$@

与$*相同,但每个参数都是带引号的字符串,也就是说,参数是完整传递的,没有解释或扩展。这意味着,除其他外,参数列表中的每个参数都被视为一个单独的单词

这对于通配符扩展问题可能很有用

移位后,$@保留其余的命令行参数,缺少先前丢失的$1

这是一种从第二个参数开始指定所有参数的方法

我希望这有帮助

如果有办法指定“从第二个参数开始的所有参数”,我不知道

它是
“${@:2}”
,如:

find "$1" ! \( -name .backup -prune \) "${@:2}"
是一个有点密集的阅读,但它确实描述了这种行为,如果你知道去哪里看的话。具体地说,在§3.5.3外壳参数扩展中,在
${Parameter:offset}
${Parameter:offset:length}
的描述中,它提到“如果参数是'@',结果是从offset开始的长度位置参数”,然后是除非使用位置参数,否则子字符串索引是从零开始的,在这种情况下,索引默认从1开始

如果有办法指定“从第二个参数开始的所有参数”,我不知道

它是
“${@:2}”
,如:

find "$1" ! \( -name .backup -prune \) "${@:2}"
是一个有点密集的读取,但是如果您知道在哪里可以看到,它确实描述了这种行为。具体来说,在§3.5.3 Shell参数扩展中,
${Parameter:offset}
${Parameter:offset:le>的描述中