2017-09-18 192 views
1

用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。 –

回答

0

我假設你需要一個沒有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]中。