可以找到搜索指定输入变量的多个顺序变体

时间:2014-04-30 19:51:50

标签: bash find

我希望能够运行一个查找,该查找使用用户输入值($ 1 $ 2 $ 3 .. $ 9或$#的值)的所有可能变化来查看文件是否存在。但是一旦用户只输入3个参数(搜索模式),find命令开始变得有点笨拙:

docs=($(find /dir1 /dir2 -type f -iname "*$1*$2*$3" -o -iname "*$1*$3*$2" -o -iname "*$2*$1*$3" -o -iname "*$2*$3*$1*" -o -iname "*$3*$1*$2*" -o -iname "*$3*$2*$1*" ))

有没有办法告诉find获取指定的多个模式并搜索每个可能的顺序变量以查看文件是否存在?对于大多数情况,我想用户只会输入2-4个输入参数,但我想允许使用最多9个输入变量进行搜索,而我讨厌想象$#= 9时的find命令。< / p>

1 个答案:

答案 0 :(得分:2)

我喜欢你的问题。您需要生成位置参数的所有排列。很有趣:

#!/bin/bash

perms() {
   if (($#==1)); then 
      ary_perms=( "$1" )
      return
   fi
   local i
   local ary=()
   for ((i=1;i<=$#;++i)); do
      perms "${@:1:i-1}" "${@:i+1}"
      ary+=( "${ary_perms[@]/#/${!i}$sep}" )
   done
   ary_perms=( "${ary[@]}" )
}

sep='*'
perms "$@"

searchargs=()
for s in "${ary_perms[@]}"; do
   searchargs+=( -o -iname "*$s*" )
done
searchargs=( "${searchargs[@]:1}" )

find /dir1 /dir2 "${searchargs[@]}"

函数perm以有趣符号(空格,换行符等)100%安全的方式生成给定参数的所有排列。它是一个简单的递归函数,所以如果用太多的参数提供它可能会很快爆炸,但是,嘿,你不想生成一个包含40个元素的集合的所有排列,对吗?


现在这当然是一个非常糟糕的方法!你当然不想这样做。

而不是

find /dir1 /dir2 -type f -iname "*$1*$2*$3*" -o -iname "*$1*$3*$2*" -o -iname "*$2*$1*$3*" -o -iname "*$2*$3*$1*" -o -iname "*$3*$1*$2*" -o -iname "*$3*$2*$1*"

为什么不呢?

find /dir1 /dir2 -type f -iname "*$1*" -iname "*$2*" -iname "*$3*"

-iname&#39;之间隐含

如果您需要一个脚本来构建搜索命令:

#!/bin/bash

searchargs=()
for i; do
    searchargs+=( -iname "*$i*" )
done
find /dir1 /dir2 -type f "${searchargs[@]}"

好多了,嗯?

当然,如果你有重复的论点,这并不完全等同于以前的排列mumbo。但嘿,谁在乎,真的吗?代码简单性在这里获胜。


哦,最后一句话,做:

docs=( $(find ...) )

非常糟糕(想想带有空格的文件名)。