パターンの後のnライン、パターンの前のmラインの削除

パターンの後のnライン、パターンの前のmラインの削除

ノート:私はこの質問を知っています:逆方向にgrepして「前」および「後」の行を除外する方法。私は以前の引用と重複しません。その質問に対する回答もパターンを削除しますが、この質問ではパターン自体が残るはずです。


パターンを削除せずに、パターンの後のn行とパターンの前のm行を削除しようとしています。たとえば、ファイルが次のような場合:

1
2
3
4
5
6
7
8
9

パターン=5の場合、n=2、m=3である。しかし:

1
5
8
9

これを行う方法を提案できますか?


ボーナス: 同じコードで m または n = 0 に設定できればいいと思います。例えば。上記の例で m=0 および n=1 に設定すると、次のような結果が得られます。

1
2
3
4
5
7
8
9

ベストアンサー1

あなたの一般的な質問に答えるために、私たちはed与えられた入力タイプに従って適切なコードを事前に構築します。

 re=5 n=2 m=3
 code=$(
   prev="/$re/-$m,/$re/-1d"
   next="/$re/+1,/$re/+${n}d"
    case "$m/$n" in
       0/0) set -- ;;
       0/?*) set -- "$next" "w" ;;
       ?*/0) set -- "$prev" "w" ;;
         *) set -- "$prev" "$next" "w" ;;
    esac
    printf '%s\n' ${1+"$@"} "q" 
 ) 
 ed -s filename - <<eof
 $code
 eof

1つのアプローチは次のとおりです。edエディタを使用して相対アドレス指定を実行します。これが質問の中心だからです。

 n=3 m=2 re=5
 ed -s filename - <<eof
 /$re/-$m,/$re/-1d
 .+1,.+${n}d
 wq
 eof

説明する:

 1. Line 3 after var substitution becomes
            /5/-2,/5/-1
      What it does is, sitting on line which satisfies the regex /5/, it looks 2 lines behind and stops looking 1 line before the /5/ line or the current line and deletes that bunch. Remember the current line is not deleted.

   2.  Line 4, after var sub becomes
                .+1,.+3d
       . is the nickname for the current line, which in our case is /5/
       So, starting fron one line after the current upto 3 lines after the current, delete them all. Note the current line is still untouched.

  3. Line 5 is wq which means save the modified file back onto itself and quit.

For more on info google the manual for gnu ed editor. 

おすすめ記事