2017-01-25 2 views
-3

grep/awk/bash/etcを使用してファイル内のパターンの最後のオカレンスを削除する最も簡単な方法は何ですか?たとえば、「hello world」という表現が複数回現れるファイルがあり、その行全体または「hello world」の最後の時刻だけを削除したいと思うファイルがあります。ありがとう!grep/awk/bash/etcを使用してファイル内のパターンの最後のオカレンスを削除するにはどうしたらいいですか?

+0

あなたが信じているとは反対に、StackOverflowは無料のコーディングサービス(または試験回答サービス)ではありません。関連するサンプル入力、予想される出力、実際のエラーメッセージ、そしてどこに行き詰まっているかに関するあなたのコメントとともに、コードを表示することが期待されます。この問題を解決するために最善の努力を尽くしてください(コード/データ/出力/エラーメッセージを正しくフォーマットするために、エディットボックスの左上にある{}ツールを使用してください)、人々があなたを助けることができるかもしれません。がんばろう。 – shellter

+0

そして、http://stackoverflow.com/help/how-to-ask、http://stackoverflow.com/help/dont-ask、http://stackoverflow.com/help/mcveを読んで[ツアー](http://stackoverflow.com/tour)よりQをここに投稿してください。ありがとう。 – shellter

答えて

1

あなたがGNUのcoreutilsのを持って起こる(またはあなたがそれらをインストールするために喜んでいる)あなたはこの問題を処理するためにできるように、あなたが処理のためにファイルを反転するために、時々便利tacコマンドを使用することができる場合「と最初の発生を削除やや単純であるパターン」、の:

tac /path/to/file | awk '!found && /Hello, world/{found=1;next}1' | tac 

そうしないと、あなたが最後にそれらすべてをプリントアウトできるように、メモリ内のファイルのすべての行をバッファリングするような何かをする必要があります。あなたがファイルを2回処理することができたり、最初の時間はちょうど省略する行番号を探して、それはデータをファイルではなく、あなたがコマンドにパイプしている流れにあることが必要です。

awk \ 
    -v line="$(grep -hn "hello world" /path/to/file | tail -n1 | cut -f1 -d:)" \ 
    "{NR != line}" /path/to/file 
1

あなたは行うことができます。

awk '/^hello world/ {max=NR} 
    {a[NR]=$0} 
    END{for (i=1;i<=NR;i++) {if (i!=max) print a[i]}}' file 

または、ファイルサイズが懸念される場合は、それを2回横断し、マッチをカウントするgrepを使用します。 awkで最後の試合をスキップ:

awk -v last=$(grep -c '^hello world' file) '/^hello world/ && ++cnt==last{ next } 1 ' file 
1
あなたは二回、ファイルを読むことができ、かつ tac

入力

[[email protected] tmp]$ cat f 
1 hai 
2 hello 
3 this 
4 is 
5 test 
6 hello 
7 this 
8 is 
9 test 

出力

の必要はありません以下のように配列することなく、これを達成することができます

[[email protected] tmp]$ awk 'last==FNR{next}FNR!=NR{print;next}/hello/{last=FNR}' f f 
1 hai 
2 hello 
3 this 
4 is 
5 test 
7 this 
8 is 
9 test 

説明

NR - それは、処理されたレコードの合計数を示します。

FNR - 各入力ファイルの合計レコード数を示します。

awk ' 
     # while reading file first time it always evaluate to Boolean false 
     # This part executes always but will skip line from 
     # file while reading second time 
     last==FNR{ 
        next 
     } 

     # while reading file first time it always evaluate to Boolean false 
     # This part prints line when reading file second time 
     # immediately after print stop processing and go to next line 
     FNR!=NR{ 
       print 
       next 
     } 

     # (1) executes first, read first file 
     # search for word hello and save line number in variable last 
     /hello/{ 
       last=FNR 
     } 
    ' f f       # Here we are reading file twice 
関連する問題