【问题标题】:grep utility in shell scriptshell 脚本中的 grep 实用程序
【发布时间】:2010-12-05 09:00:09
【问题描述】:

我正在尝试克服我们文件结构的限制。我想在已知位置 grep 一系列文件。如果我从命令行执行标准 grep

(grep -i searchpattern known_dir/s*.sql) 

我收到以下错误:

ksh: /usr/bin/grep: 0403-027 The parameter list is too long.

所以我有一个看起来像这样的 for 循环:

searchfor=$1
for i in /$ENV_VAR_DIR/s*.sql
do
  grep -i $searchfor $i
done

当我执行这个时,我遇到了几个问题:

  1. 它给了我一行代码,但没有我需要的文件名
  2. -l 显然只给了我想要修剪路径的路径/文件名,我只是从我的主目录执行。

【问题讨论】:

  • 这是一个关于shell编程的问题;它属于 StackOverflow 而不是其他地方。

标签: shell grep


【解决方案1】:
easy_install grin    
grin -I "*.sql" searchpattern

只显示文件名

grin -I "*.sql" -l searchpattern

【讨论】:

    【解决方案2】:

    find ./known_dir/ -name "s*.sql"|xargs grep -i searchpattern

    【讨论】:

    • 抱歉我的错误是 find ./known_dir/ "s*.sql"|xargs grep -i searchpattern
    • 像魅力一样工作!我知道这要求很多,但现在有办法修剪目录路径,所以我只有文件名吗?
    • 这很好用,我认为我对我最终拥有的东西很好,这就是我最终得到的结果:for i in $1 do find $i -name $2 | xargs grep -i $3 完成
    • 我仍然认为你想要确认或微笑。去试试看。我不在乎“接受”。 :)
    【解决方案3】:

    作为一种技巧,您还可以在 grep 命令中指定 /dev/null 以获取 -l 来列出文件,但是您的方法会很慢,因为它使用 shell 循环并为每个文件启动一个 grep 进程。如前所述,findxargs 是您的朋友。

    也许您可以使用 findrepo 脚本,它似乎可以按照您的要求进行操作。

    【讨论】:

      【解决方案4】:

      我会推荐以下内容:

      $ find known_dir -name 's*.sql' -print0 | xargs -0 grep -i searchpattern
      

      使用xargs,您可以使用-n 选项更改每次传递给grep 的最大文件数。

      -print0-0 选项用于防止文件名中出现空格。

      您甚至可以使用-P 选项在多个内核上并行计算多个grep 命令。

      【讨论】:

      • 在搜索模式之后添加 /dev/null 并获得文件名(因为命令行上总是至少有两个文件,/dev/null 和 find 找到的任何文件)。
      • 您还可以在某些版本的“grep”(但不是全部)上使用“-H”来无条件列出文件名。
      【解决方案5】:
      ls | read fname; do
          grep searchpattern $fname /dev/null
      done
      

      这为你做了两件事。

      1. 您无需一次展开所有文件,它一次处理一个。
      2. 通过将 /dev/null 作为第二个文件列出,它不会匹配任何内容,但它会得到 grep 来打印文件名。 Gnu grep 有一个强制文件名输出的选项,但这适用于任何 unix。

      与此 shell 设计模式有关的另一项传统做法是向循环提供 find

      find . -name "*.sql" | read fname; do
          grep searchpattern $fname /dev/null
      done
      

      您可能还想让searchpattern 成为$1

      【讨论】:

      • 小心带有空格的路径名!
      • 没错,每个$fname 都应该是"$fname""*.sql" 应该是'*.sql'
      【解决方案6】:

      您想要ackgrin

      【讨论】:

        【解决方案7】:

        grep -H 将强制将文件名附加到每个输出行,就像您执行原始单个命令时一样。

        获取文件名的最简单方法(无论是来自-H 还是-l)是在运行命令时将该目录作为当前工作目录:

        searchfor=$1
        cd /$ENV_VAR_DIR
        for i in s*.sql
        do
          grep -Hi $searchfor $i
        done
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-10-26
          • 1970-01-01
          • 2016-03-05
          • 2017-03-15
          • 2023-02-06
          • 2011-05-21
          • 2014-04-21
          • 2012-08-08
          相关资源
          最近更新 更多