使用bash脚本设置“查找”实用程序的参数的麻烦

时间:2011-12-16 01:48:43

标签: bash find wildcard

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

Bash脚本不是我强大的套件。我一直坚持如何在命令行中将引用的通配符文件规范引入脚本,并从那里进入未命令的find命令。看起来像bash喜欢从内容中删除引号并将包含通配符的单词扩展为单词列表,这通常很棒,但是当我尝试评估脚本中的“查找”时,此命令行烹饪发生两次,有不良后果。

现在我要给出血腥的细节,或许有人会看到我真正想要做的事情并说'嘿,你知道有一种更简单的方法可以完全做到这一点'。关于这个问题的最终结果对我很好。

所以,背景 -

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

例如,假设我想查找所有* .foo文件;简单的解决方案是发布

find ~ -name "*.foo"

..除了在这台机器上,find开始筛选所有这些备份目录。通常我对.backup目录中的命中率不感兴趣。搜索它们很慢,而且据我所知,它们是网络安装的,我正在融化某人的数据柜。所以接下来的进化是用这样的形式做某事

find ~ ! \( -name .backup -prune \) -a -name "*.foo"

..哪个有效,如果只需要使用一次或两次就不会太糟糕。但它很容易发胖,并且在需要连续几次时会变得烦人。所以编写一个脚本来处理这个问题似乎是一个好主意。由于缺乏更具想象力的名称,让我们使用'findx'。想法是发出findx~-name“* .foo”,并让'findx'自动将其转换为更复杂的形式。脚本的第一个黑客看起来像这样

find $1 ! \( -name .backup -prune \) $2 $3 $4 $5 $6 $7

不可否认,这看起来非常糟糕,并且不适用于参数太多的搜索。 (如果有办法指定'从第二个开始的所有参数',我不知道。)find命令的特殊语法似乎要求从其余参数中分割$ 1,b / c搜索根如果它们的顺序相反,则-prune和-print子句不能正常工作,所以-prune必须在(隐式)打印的东西之前,在右边留下$ 2 $ 3等。无论如何,它应该足够简单的搜索。

嗯,这对于特定的文件名似乎没问题,但是通配符让它失败了。似乎,例如,如果我喂它

findx . -name "*stuff"

bash 首先将引号删除*之前将其作为$ params之一传递给脚本。然后构建的find命令没有包装通配符的引号;因此当 执行时,shell会在执行find之前扩展*,然后choke,b / c find想要一个单词* stuff而不是它扩展到的列表。 (显然发现喜欢做自己的通配符扩展?)

那么 - 有没有办法使这项工作?是否有其他方法可以省略搜索不仅仅是如此冗长的目录,从而避免了脚本的动机?查找的替代方法,可以执行大多数查找操作,例如-ctime,-type,-name等等?

2 个答案:

答案 0 :(得分:3)

  

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

它是"${@:2}",如:

find "$1" ! \( -name .backup -prune \) "${@:2}"

The Bash Reference Manual是一个密集的读取,但它确实描述了这种行为,如果你知道在哪里看。具体来说,在§3.5.3壳参数扩展中,在${parameter:offset}${parameter:offset:length}的描述中,它提到“如果参数是'@',结果是 length 位置参数从 offset “开始,后来”除非使用位置参数,否则子串索引从零开始,在这种情况下,索引默认从1开始。“< / p>

答案 1 :(得分:2)

不是一个完整的答案,但看着ABS Guide,我看到了一些有趣的事情。

  

$ @

     

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

这对于通配符扩展问题非常有用。

  

在转换之后,$ @保留剩余的命令行参数,缺少先前的$ 1,这些参数丢失了。

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

我希望这会有所帮助。