web-dev-qa-db-ja.com

テキストファイルを行数で制限(または切り捨て)するにはどうすればよいですか?

ターミナル/シェルを使用して、テキストファイルを切り捨てるか、特定の行数に制限したいと思います。

テキストファイルのディレクトリ全体があり、それぞれの最初の〜50k行だけが役に立ちます。

50000を超えるすべての行を削除するにはどうすればよいですか?

30
sjmurphy

インプレーストランケーション

Sedを使用してインプレースでファイルを切り捨てるには、次のようにします。

_sed -i '50001,$ d' filename
_
  • _-i_は所定の位置にあることを意味します。
  • dは削除を意味します。
  • _50001,$_は50001から最後までの行を意味します。

_-i_に拡張引数を追加することにより、ファイルのバックアップを作成できます。たとえば、_.backup_または_.bak_:

_sed -i.backup '50001,$ d' filename
_

OS-XまたはFreeBSD では、_-i_に引数を指定する必要があります-バックアップを作成せずにこれを行うには:

_sed -i '' '50001,$ d' filename
_

長い引数名のバージョンは次のとおりで、backup引数がある場合とない場合があります。

_sed --in-place '50001,$ d' filename
sed --in-place=.backup '50001,$ d' filename
_

新しいファイル

新しい切り捨てられたファイルを作成するには、headから新しいファイルにリダイレクトするだけです。

_head -n50000 oldfilename > newfilename
_
  • _-n50000_は行数を意味します。それ以外の場合、デフォルトは10です。
  • _>_は、リダイレクトしてそこにある可能性のある他のものを上書きすることを意味します。
  • 新しいファイルに追加する場合は、_>>_を_>_に置き換えます。

同じファイルにリダイレクトできないのは残念です。そのため、インプレーストランケーションにはsedをお勧めします。

セッドなし? Pythonをお試しください!

これは、sedよりもタイピングが少し多いです。 Sedは、結局のところ「Stream Editor」の略であり、それがこのツールを使用するもう1つの理由であり、このツールに適しています。

これは、LinuxおよびWindowsでPython3を使用してテストされました。

_from collections import deque
from itertools import islice

def truncate(filename, lines):
    with open(filename, 'r+') as f:
        blackhole = deque((),0).extend
        file_iterator = iter(f.readline, '')
        blackhole(islice(file_iterator, lines))
        f.truncate(f.tell())
_

Pythonを説明するには:

ブラックホールは_/dev/null_のように機能します。これは、_maxlen=0_でextendにバインドされたdequeメソッドです。これは、Python(私が知っている)でイテレータを使い果たす最も速い方法です。

tellメソッドがブロックされるため、単純にファイルオブジェクトをループすることはできません。したがって、iter(f.readline, '')トリックが必要です。

この関数はコンテキストマネージャを示していますが、Pythonが関数の終了時にファイルを閉じるため、少し不必要です。使い方は簡単です:

_>>> truncate('filename', 50000)
_
60
Aaron Hall

確かにsedを使用すると非常に簡単です。

sed -n '1,50000 p' filename

これは、ファイル 'filename'の1行から50000行だけを印刷します。

3
tdk2fe