2011-01-28 39 views
0

如何在搜索一行後獲取文件的上一行?如何在搜索特定行後輸出文件的上一行?

例子:有一個叫fore.dat包含文件:

:Server:APBS 

     :Max Blocking queue:20 

:Transport:000 

     :Server:APBS 

     :Max Transactions:10 

     :MaxConnections:1 

:Transport:001 

     :Server:APBS 

     :Max Transactions:10 

     :MaxConnections:1 

:Transport:005 
     :Server:BIT 

     :Max Transactions:10 

     :Max Connections:1 

:Transport:004 

     :Server:APBS 

     :Max Transactions:44440 

     :Max Connections:1 

:Transport:002 

     :Server:BET 

     :Max Transactions:10 

     :Max Connections:1 

:Transport:003 

     :Server:APBS 

     :Max Transactions:50 

     :Max Connections:1 

我要打印包含服務器名稱爲APBS運輸數量。 即;輸出爲:

:Transport:000 

:Transport:001 

:Transport:004 

:Transport:003 
+1

由於'grep -B1'不起作用,因此您沒有使用Linux。不幸的是,現在,你必須規定你不使用Linux,否則你將使用GNU工具得到答案,GNU工具對非Linux工具有很多擴展。有時,這意味着GNU比Linux更符合POSIX標準。當然,一種選擇是安裝GNU工具(但不要將它們安裝在系統bin目錄中)。 – 2011-01-28 14:50:58

回答

1

這看起來像awk工作,它甚至應該在AIX上運行,你沒有gawk做...

% awk -F':' ' 
/^:Transport:/ { 
    transport = $0 
} 

NF == 3 && $2 == "Server" && $3 == "APBS" { 
    printf "%s\n\n", transport 
} 

' fore.dat 


:Transport:000 

:Transport:001 

:Transport:004 

:Transport:003 

說明:

  • 呼叫awk
  • 款待「 :'作爲字段分隔符。
  • 對於任何以':Transport:'開頭的行,將整行存儲爲transport
  • 對於任何具有三個字段(其中第二個是「服務器」,第三個是「APBS」)的行,打印最後一個存儲的值transport,後跟一對換行符。
  • 使用fore.dat作爲輸入文件。

有很多不同的方法可以做到這一點。這只是一個。

0

你需要給什麼語言您正在使用一個更詳細一點。

這是我會做的。我會掃描文件的每一行。我會把'最後讀取'行放入緩衝區。如果下一行包含您要查找的內容,請輸出存儲在緩衝區中的行。

+0

但是,如果文件太大,難以閱讀整個文件。所以我想grep到特定的單詞和打印hte先前的行。 iam與unix合作。 – suvitha 2011-01-28 14:28:54

+0

我不確定我關注。你可能需要編寫一個腳本來做到這一點。 grep也將一次讀取整個文件行。你在Unix環境中可以使用哪些腳本語言? Python,Perl,bash? – 2011-01-28 19:29:17

0

grep -B1 APBS <filename>返回包含APBS和上面一行的行。

grep -B1 APBS <filename>| grep Transport將返回包含運輸號的行。

0

在讀取一行(actual_line)之前,將您所擁有的行存儲在臨時變量(previous_line)中。當你找到你需要的那個(actual_line是你要找的那個)時,只需返回前一個(previous_line)

0

鑑於你沒有使用GNU grep並假設你不能安裝它,那麼你必須下降回到其他工具上。這是一個我稱爲'sgrep'的腳本,從日期信息中可以看到,它是相當古老的,但是爲Xenix,SunOS(Solaris之前的版本),HP-UX,AIX以及其他久已消失的軍團Unix的變種。它相當徹底地完成了這項工作 - 它比你目前需要的更全面。

: "$Id: sgrep.sh,v 1.3 1989/05/12 10:24:14 john Exp $" 
# 
# Special grep 
# Finds a pattern and prints lines either side of the pattern 
# Line numbers are always produced by ed (substitute for grep), 
# which allows us to eliminate duplicate lines cleanly. If the 
# user did not ask for numbers, these are then stripped out. 
# 
# BUG: if the pattern occurs in in the first line or two and 
# the number of lines to go back is larger than the line number, 
# it fails dismally. 

set -- `getopt "f:b:n" "[email protected]"` 

case $# in 
0) echo "Usage: $0 [-n] [-f x] [-b y] pattern [files]" >&2 
    exit 1;; 
esac 

number="'s/^\\([0-9][0-9]*\\) /\\1:/'" 
filename="'s%^%%'"  # No-op for sed 

f=3 
b=3 
nflag=no 
while [ $# -gt 0 ] 
do 
    case $1 in 
    -f) f=$2; shift 2;; 
    -b) b=$2; shift 2;; 
    -n) nflag=yes; shift;; 
    --) shift; break;; 
    *) echo "Unknown option $1" >&2 
     exit 1;; 
    esac 
done 
pattern="${1:?'No pattern'}" 
shift 

case $# in 
0) tmp=${TMPDIR:-/tmp}/`basename $0`.$$ 
    trap "rm -f $tmp ; exit 1" 0 
    cat - >$tmp 
    set -- $tmp 
    sort="sort -t: -u +0n -1" 
    ;; 
*) filename="'s%^%'\$file:%" 
    sort="sort -t: -u +1n -2" 
    ;; 
esac 

for file in $* 
do 
    { 
    ed - $file <<-! 
    g/$pattern/.-${b},.+${f}n 
    ! 
    } | 
    eval sed -e "$number" -e "$filename" \| $sort | 
    case $nflag in 
    yes) cat -;; 
    no)  sed 's/[0-9][0-9]*://';; 
    esac 
done 

rm -f $tmp 
trap 0 
exit 0 

我不得不挖掘出來化石牀,我保留古老的軟件。我有一個基本上完成相同工作的Perl腳本;我不常使用,因爲我通常安裝了GNU grep。

相關問題