无法在UNIX Shell脚本

问题描述:

用grep的-C我能够在正常的命令行中使用grep无法在UNIX Shell脚本

grep "ABC" Filename -C4 

这给了我想要的输出,它是在匹配的图案线的上方和下方4行。

但是,如果我在Unix shell脚本中使用相同的命令,我不能到grep上方和下方的图案线条。这是给我到底是哪里模式匹配的唯一线路输出和一个错误,不能说不能打开grep-C4

结果是相似的,如果我使用-A4-B4

+1

更新您的Q随的'UNAME -srv'输出。我打赌你使用的是旧版本的SunOS(或许多其他版本),其中' - [ABC]'选项不可用。但是,因为它在你的cmd行上工作,你需要输入'which grep',然后在脚本中使用像'/ path/to/ABCgrep/grep'这样的完整路径,或者覆盖PATH设置,如'export PATH =“/path/to/ABCgrep/grep:$ PATH“'。祝你好运。 – shellter

+1

将文件名前的选项:'grep -C4“ABC”文件名“。如果这也行不通,那么你运行的shell脚本运行的'grep'不同 - 你需要为你使用的'grep'找到正确的路径,并在脚本中使用它。 '-A','-B'和'-C'选项是GNU扩展; o/s命令可能不支持它们。您没有确定您使用的平台 - 如果它是Linux,那不会是问题,但如果它是Solaris或AIX或HP-UX,则可能是问题所在。由于您没有使用Linux标签,因此您使用的可能不是Linux。 –

我假设你需要一个没有GNU扩展的便携POSIX解决方案(-C NUM,-A NUM-B NUM都是GNU,因为模式和/或文件名后面的参数)。

POSIX grep不能做到这一点,但POSIX awk即可。这可以被调用为例如grepC -C4 "ABC" Filename(假设它被命名为“grepC”,是可执行的,并且是在你的$PATH):

#!/bin/sh 

die() { echo "$*\nUsage: $0 [-C NUMBER] PATTERN [FILE]..." >&2; exit 2; } 

CONTEXT=0 # default value 

case $1 in 
    -C ) CONTEXT="$2"; shift 2 ;;  # extract "4" from "-C 4" 
    -C*) CONTEXT="${1#-C}"; shift ;;  # extract "4" from "-C4" 
    --|-) shift ;;      # no args or use std input (implicit) 
    -* ) [ -f "$1" ] || die "Illegal option '$1'" ;; # non-option non-file 
esac 

[ "$CONTEXT" -ge 0 ] 2>/dev/null || die "Invalid context '$CONTEXT'" 
[ "$#" = 0 ] && die "Missing PATTERN" 

PATTERN="$1" 
shift 

awk ' 
    /'"$PATTERN"'/ { 
    match='$CONTEXT' 
    for(i=1; i<=CONTEXT; i++) if(NR>i) print last[i]; 
    print 
    next 
    } 
    match { print; match-- } 
    { for(i='$CONTEXT'; i>1; i--) last[i] = last[i-1]; last[1] = $0 } 
' "[email protected]" 

这就建立die作为致命误差函数,然后查找上下文的所希望的线从您的参数(或者-C NUMBER-CNUMBER),对于不支持的选项有一个错误(除非它们是文件)。

如果上下文不是数字或没有图案,我们又致命的错误了。

否则,我们节省模式,转向它扔掉,并保留选项的休息递给AWK为文件("[email protected]")。

有三节在此AWK调用:

  1. 匹配的模式本身。这需要结束字符串的单引号部分,以便合并变量$PATTERN(如果通过awk -v导入,变量可能不会正确)。在匹配之后,我们将上下文的行数存储到match变量中,循环通过保存在last哈希中的以前的行(如果我们走得足够远以获得它们)并打印它们。然后,我们跳到下一行,而不评估其他两节。
  2. 如果有匹配,我们需要接下来的几行作为上下文。当这节打印它们时,它会减少计数器。新的比赛(前一节)将重置该计数。
  3. 我们需要保存以前的线路才能在比赛中进行调用。这循环遍历我们关心的上下文的行数并将它们存储在last散列中。当前行($0)存储在last[1]中。