【问题标题】:Using * in grep path called from bash script在从 bash 脚本调用的 grep 路径中使用 *
【发布时间】:2013-09-20 21:44:28
【问题描述】:

我正在尝试编写一个 bash 脚本来使用 grep 在我的源目录中搜索字符串——不,我不能使用 ack

目录结构是

标题:.../product/package/product-module/i/filename.h

来源:.../product/package/product-module/s/filename.c

我想选择是否指定module(搜索所有模块),这是$2 的论点。问题是,我无法让 *$2"*$2" 在脚本中工作(请参阅下文)。

edit: 前者的尝试没有任何输出,后者的结果是“grep: No such file or directory”

如果我想将*grep 与另一个字符串复合,如何正确使用它?

#!/bin/bash

# Usage: search_src -[si] < module | all > < target >

if [ $1 == "-s" ]; then
   fext="c"
   subdir="s"
elif [ $1 == "-i" ]; then
   fext="h"
   subdir="i"
else
   fext="[ch]"
   subdir="[si]"
fi

if [ $2 == "all" ]; then
   module=*;
else
   module=*$2;
fi

shift 2;

grep \"$@\" ~/workspace/*/package/$module/$subdir/*.$fext

【问题讨论】:

  • 您在寻找像grep -r *.{c,h} 这样的人吗? -r 可以选择递归复制!
  • 不,据我了解,-r 将报告所有子目录中的匹配项,但此脚本的目的是只查看其中的一些。

标签: bash grep wildcard


【解决方案1】:

只需使用安全的评估和一些小的修改:

#!/bin/bash

# Usage: search_src -[si] < module | all > < target >

if [[ $1 == "-s" ]]; then
   fext="c"
   subdir="s"
elif [[ $1 == "-i" ]]; then
   fext="h"
   subdir="i"
else
   fext="[ch]"
   subdir="[si]"
fi

if [[ $2 == "all" ]]; then
   module='*';
else
   module='*"$2"';
fi

shopt -s nullglob
eval "files=(~/workspace/*/package/$module/$subdir/*.$fext)"

IFS=$' \t\n'
[[ $# -gt 2 && ${#files[@]} -gt 0 ]] && grep -e "${*:3}" -- "${files[@]}"

【讨论】:

  • 谢谢!只是一个小问题......如果我发出search_sh -s all hello world,它会列出所有包含“hello”或“world”的行。脚本的原始行为会搜索“hello world”
  • 谢谢!虽然......我能够通过删除shift 2;并将最后一行修改为eval "grep \"${@:3}\" ~/workspace/*/package/$module/$subdir/*.$fext"来使其工作。我不太确定shoptIFSgrep -- 是做什么的,那么您的安全和/或性能优势是否显着? [编辑:请注意,我已经对参数进行了一些检查,但在这段代码 sn-p 中省略了它们...抱歉造成混淆]
  • @EvanW 我实际上在进一步的更新中也使用了“${*:3}”。实际上,使用 --for grep 并没有明显的优势,但有时当文件名以 - 开头时,它会被解释为选项,并导致 grep 出现语法错误。这只是一种练习。另外,关于设置 IFS,"${*:3}" 的分隔符实际上取决于它,所以这只是一个预防措施,以防 IFS 在外部变得不同并通过导出适用于脚本。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-10-17
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多