【问题标题】:wrapping bash find command包装 bash 查找命令
【发布时间】:2016-06-08 04:05:30
【问题描述】:

我想编写一个简单的 bash 脚本,将默认的 unix/linux 查找程序包装在 bash 中以查找匹配的多个文件。

这是我的名为my_find_command的程序:

#!/bin/bash

patt=""
first=true
for i in "$@"; do
  if [ "$first" = true ]; then
    patt="-name '$i'"
    first=false
  else
    patt="${patt} -o -name '$i'"
  fi
done

echo "$patt"
find . -type f \( ${patt} \)
echo 'done'

假设我确实有一些文件,find 命令可以返回一些文件。

但是当我打电话给my_find_command icon.png profile.png 时,我什么也没得到。

这里出了什么问题?

【问题讨论】:

  • 您的脚本在 Linux 上按预期运行,但您可能需要添加 -a 以获取 find . -type f -a \( $patt \) find 的不同实现是挑剔的......
  • 您可以将for 循环更简单地编写为:for x; do patt="$patt${patt:+ -o }-name '$x'"; done

标签: linux bash macos shell


【解决方案1】:

字符串中的引号按您希望的方式工作。你是对的,./my_find_command icon.png 找不到icon.png。但是,它会找到'icon.png'。例如:

$ ls
'icon.png'  my_find_command
$ ./my_find_command my_find_command icon.png 
-name 'my_find_command' -o -name 'icon.png'
./'icon.png'
done

问题来自试图将多个命令参数放在一个变量中。有关出错方式的完整说明,请参阅 "I'm trying to put a command in a variable, but the complex cases always fail!"。相反,使用数组:

#!/bin/bash    
patt=()
for i in "$@"; do
  if [ "${#patt}" -eq 0 ]; then
      patt=(-name "$i")
  else
      patt+=(-o -name "$i")
  fi
done

echo "${patt[@]}"
find . -type f \( "${patt[@]}" \)
echo 'done'

现在打印正确的文件:

$ ls
'icon.png'  icon.png  my_find_command
$ ./my_find_command my_find_command icon.png 
-name my_find_command -o -name icon.png
./icon.png
./my_find_command
done

为了证明通配符可以正常工作:

$ ls
'icon.png'  icon.png  my_find_command

$ ./my_find_command my_find_command '*icon.png*'
-name my_find_command -o -name *icon.png*
./icon.png
./my_find_command
./'icon.png'
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多