2

こんにちは、次のようなテキストブロックを削除する方法を考えていました:

1    
2    
3    
4    
5    
6    
7    
8

2 行目から最後の行の前の 3 行目までを削除すると、次のようになります。

1    
2    
6    
7    
8

前もって感謝します!!!

ところで、このテキスト ブロックは単なる例です。私が取り組んでいる実際のテキスト ブロックは巨大で、行番号がそれぞれ異なります。

4

4 に答える 4

3

wcを使用して行数を取得しawk、要求された範囲を印刷します。

$ awk 'NR<M || NR>N-M' M=3 N="$(wc -l file)" file
1
2
6
7
8

これにより、 の値を変更するだけで簡単に範囲を変更できますM

于 2013-10-05T23:22:36.987 に答える
2

あなたが巨大で、行番号も異なる可能性があると述べたので。この awk ワンライナーをお勧めします。

awk 'NR<3{print;next}{delete a[NR-3];a[NR]=$0}END{for(x=NR-2;x<=NR;x++)print a[x]}' file
  • 合計行数を(事前に)計算せずに、入力ファイルを1回だけ処理します
  • 最小限のデータをメモリに保存します。すべての処理時間で、3 行のデータのみが保存されました。
  • フィルタリング基準を変更したい場合、たとえば行xをから に削除する$-y場合は、ワンライナーのオフセットを変更するだけです。

テストを追加します。

kent$  seq 8|awk 'NR<3{print;next}{delete a[NR-3];a[NR]=$0}END{for(x=NR-2;x<=NR;x++)print a[x]}'
1
2
6
7
8
于 2013-10-05T23:20:28.880 に答える
1

使用:

sed -n '
    ## Append second line, print first two lines and delete them.
    N; 
    p; 
    s/^.*$//;
    ## Read next three lines removing leading newline character inserted
    ## by the "N" command.
    N; 
    s/^\n//; 
    N; 
    :a; 
    N;
    ## I will keep three lines in buffer until last line when I will print
    ## them and exit.
    $ { p; q };
    ## Not last line yet, so remove one line of buffer based in FIFO algorithm.
    s/^[^\n]*\n//; 
    ## Goto label "a".
    ba
' infile

次の結果が得られます。

1
2
6
7
8
于 2013-10-05T23:15:57.827 に答える