ファイル内の特定の行を(行番号を使用して)削除するにはどうすればよいですか?


27

ファイルから削除したい特定の行があります。20〜37行目、次に45行目だとします。これらの行の内容を指定せずに、どうすればよいでしょうか。


ファイルの大きさは?メモリにロードできますか?
ファヒムミタ

数キロバイト。
シェパン

回答:


29

sed、次のように:

sed '20,37d; 45d' < input.txt > output.txt

これをインプレースで行いたい場合:

sed --in-place '20,37d; 45d' file.txt

その場でそれを行う方法はありますか?
-tshepang

sed -iファイル
-enzotib

1
@Tshepang:を使用するedか、GNU sed -i、またはsponge、または大容量ファイルメソッド
ジル 'SO-悪である停止

3
私は、多くの場合、おそらく誤解を招く用語について不思議に思っていましたその場で、私は「男がセッド」でそれを見上げて、「セッド」に言及するとき、:--in-場所[= SUFFIX]は This option specifies that files are to be edited in-place. GNU sedの」一時ファイルを作成することによってこれを行います標準出力ではなく、このファイルに出力を送信します。`...他の「sed」については知りませんが、ストリームエディタで「インプレース」更新するロジスティクスは「計算」しません:)
Peter.O

2
私の経験では、ほとんどの「インプレース」メソッドは一時ファイルを使用します。
ファヒムミタ

5

ファイルがメモリに快適に収まる場合は、を使用することもできますed
コマンドはsed上記のものと非常に似ていますが、1つの顕著な違いがあります:削除する行番号/範囲のリストを降順(最高行番号/範囲から最低番号まで)で渡す必要があります。理由は、で行を削除/挿入/分割/結合するとed、各サブコマンドの後にテキストバッファーが更新されるため、一部の行を削除すると、次の行の残りがバッファー内の同じ位置になくなるためです。次のサブコマンドが実行されます。そのため、後方に開始する必要があります1
インプレース編集:

ed -s in_file <<IN
45d
20,37d
w
q
IN

または

ed -s in_file <<< $'45d\n20,37d\nw\nq\n'

または

printf '%s\n' 45d 20,37d w q | ed -s in_file

ファイルに書き込む代わりに結果の出力を印刷する場合はw,prite をrintに置き換えます。元のファイルをそのままにして別のファイルに書き込む場合は、新しいファイル名をwriteサブコマンドに渡すことができます。

ed -s in_file <<IN
78,86d
65d
51d
20,37d
w out_file
q
IN

1d各行の 後に新しい行番号を計算する意思がない限り、この特定のケースでは非常に簡単です(行20〜37、つまり18行を削除した後、行45は行27になります)。

ed -s in_file <<IN
20,37d
27d
w
q
IN

ただし、複数の行番号/範囲を削除する必要がある場合、逆方向の作業は簡単です。


あるqコマンドは、最後に便利?どちらかの方法で終了すると思います。
トム・フェネシュ

@TomFenech-すべての実装がいずれかの方法で終了するわけではありません(ほとんどの場合...これについて議論されたスレッドを見つけることができません...)
don_crissti

1

それをメモリに読み込み、変更してから書き戻します。次のようなことができます

filename = "foo"
f = open(filename, 'r+')                                                                                                                                 
linenums = [1, 3]                                                                                                                                            
s = [y for x, y in enumerate(f) if x not in [line-1 for line in linenums]]                                                                                                                                          
f.seek(0)
f.write(''.join(s))
f.truncate(f.tell())
f.close()

5行のファイルでテスト済み。クレジットhttp://pleac.sourceforge.net/pleac_python/fileaccess.htmlは、「一時ファイルない場所でのファイルの変更」を参照してください。https://stackoverflow.com/questions/125703/how-do-i-modify-a-text-file-in-pythonも参照してください

いくつかのメモ:

  1. 上記のように、ファイルを切り捨ててから書き込むのではなく、最初にファイルを切り捨ててから書き込むことができます。ただし、Pythonフラグを使用して読み取りを許可した後、切り捨てられた書き込みを行うことはできません。しかし、ドキュメントがそれほど明確ではないため、何かが欠けているのかもしれません。それが私をもたらします

  2. 時々Pythonのドキュメントは本当にひどいものです。http://docs.python.org/library/functions.html#openを参照してください

    モード「r +」、「w +」、および「a +」は、更新のためにファイルを開きます(「w +」はファイルを切り捨てます)。

    これはあなたにとって何か意味がありますか?一体何が「更新のために開かれている」のでしょうか?

  3. ストリームエディタのようなunixyの方が優れているのに対して、Pythonでこれを行うかどうかはわかりません。移植性は高いかもしれませんが、sedの移植性はわかりません。私はちょうどそのように書いたのは、私が古典的なUnixツールを使用するよりも低レベルのプログラミングに慣れているからです。

  4. このアプローチ(メモリ内のファイルの操作)は、メモリをディスク領域と引き換えにします。最大数百Mbのファイル用に数Gbのメモリを搭載したマシンでは問題なく動作するはずです。Pythonは文字列をあま​​り効率的に処理しないため、たとえばC / C ++に切り替えると、パフォーマンスがわずかに向上し、メモリ使用量が大幅に削減されます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.