2014-09-25 87 views

回答

3

這裏有一種方法可以使用awk來完成。我假設你也想刪除的行本身和文件小到足以放入內存:

awk '{a[NR]=$0}/xxxx/{f=NR}END{for(i=1;i<=NR;++i)if(i<f-5||i>f+6)print a[i]}' file 

商店每行入陣a。當匹配的模式/xxxx/時,保存行號。整個文件處理完畢後,循環訪問數組,只打印要保留的行。

或者,也可以使用grep首先獲得的行號:

grep -n 'xxxx' file | awk -F: 'NR==FNR{f=$1}NR<f-5||NR>f+6' - file 

在兩種情況下,刪除將被周圍的最後一行,其中模式匹配的行。

第三種選擇是用grep獲得的行號,然後用sed刪除行:

line=$(grep -nm1 'xxxx' file | cut -d: -f1) 
sed "$((line-5)),$((line+6))d" file 

在這種情況下我還添加了-m開關找到第一個之後這樣的grep退出比賽。

1

,如果你知道,行號(究竟是不是很難獲得),可以使用類似的東西:

filename="test" 
start=`expr $curr_line - 5` 
end=`expr $curr_line + 6` 

sed "${start},${end}d" $filename (optionally sed -i) 
當然

,你必須要記住的附加條件,如啓動不應該小於1並結束大於文件中的行數。

3

這可能爲你工作(GNU SED):

sed ':a;N;s/\n/&/5;Ta;/xxxx/!{P;D};:b;N;s/\n/&/11;Tb;d' file 

保持5行滾動窗口,並在遇到指定的字符串添加6個(11個)和刪除。

N.B.這是一個barebones解決方案,很可能需要根據您的特定需求進行定製。問題如:如果整個文件中有多個字符串呢?如果字符串在前五行或者多個字符串在彼此的五行之內等等,等等等等。

0

另一個 - 也許更容易遵循 - 解決方案將使用grep找到關鍵字和相應的行:

grep -n 'KEYWORD' <file> 

然後使用sed只得到這樣的行號:

grep -n 'KEYWORD' <file> | sed 's/:.*//' 

現在,你有行號只需使用sed這樣的:

sed -i "$(LINE_START),$(LINE_END) d" <file> 

刪除之前和/或之後的行!只有-i您將覆蓋<file>(無備份)。

腳本例子是:

#!/bin/bash 

KEYWORD=$1 
LINES_BEFORE=$2 
LINES_AFTER=$3 
FILE=$4 

LINE_NO=$(grep -n $KEYWORD $FILE | sed 's/:.*//') 
echo "Keyword found in line: $LINE_NO" 

LINE_START=$(($LINE_NO-$LINES_BEFORE)) 
LINE_END=$(($LINE_NO+$LINES_AFTER)) 
echo "Deleting lines $LINE_START to $LINE_END!" 

sed -i "$LINE_START,$LINE_END d" $FILE 

請注意,如果關鍵字被發現一次,這隻會工作!根據您的需求調整腳本!

相關問題