ソートは、 `sed --in-place`のように、ファイルをインプレースでソートすることをサポートしていますか?


80

私は盲目ですか--in-placesortそれともオプションはありませんか?

入力ファイルに結果を保存するために、sedは-i--in-place)を使用します。

の出力をsort入力ファイルにリダイレクトする

sort < f > f

空になります。--in-placeオプションがない場合- 便利な方法でこれを行う方法がありますか?

(私の頭に浮かんだ唯一のもの:

sort < f > /tmp/f$$ ; cat /tmp/f$$ > f ; rm /tmp/f$$

移動は正しい選択ではありません。ファイルのアクセス許可が変更される可能性があります。そのため、一時ファイルの内容で上書きし、その後削除します。)


またinsitu、すべてのコマンドをインプレースで使用できるようにします。
sr_

@sr_、これは興味深いコマンドですが、どのコマンドで機能せず、読むよりも速く書かないコマンドのみです(そうしないと、コマンドが読み取る前に入力ファイルを上書きします)。で動作するという保証はありませんsort
cjm

@cjm、私は本当にわからないんだけど、されていない、これはそのケースを扱うことになって?
sr_

@sr_、あなたは正しいと思います。ソースを見る代わりに説明を読みました。本当に大きなファイルの場合、バッファのメモリが不足してクラッシュする可能性があります(mallocからのNULLリターンをチェックするようには見えません)。
cjm

@cjm:そうそう、確かに。
sr_

回答:


110

sort持っている-o, --output引数としてファイル名を取るオプションを選択します。入力ファイルと同じ場合は、結果を一時ファイルに書き込み、元の入力ファイルを上書きします(実行内容とまったく同じですsed -i)。

GNU sort情報ページから:

`-o OUTPUT-FILE'
`--output=OUTPUT-FILE'
      Write output to OUTPUT-FILE instead of standard output.  Normally,
      `sort' reads all input before opening OUTPUT-FILE, so you can
      safely sort a file in place by using commands like `sort -o F F'
      and `cat F | sort -o F'.  However, `sort' with `--merge' (`-m')
      can open the output file before reading all input, so a command
      like `cat F | sort -m -o F - G' is not safe as `sort' might start
      writing `F' before `cat' is done reading it.

      On newer systems, `-o' cannot appear after an input file if
      `POSIXLY_CORRECT' is set, e.g., `sort F -o F'.  Portable scripts
      should specify `-o OUTPUT-FILE' before any input files.

以下とからOpen Groupの基本仕様7号

-o  output
    Specify the name of an output file to be used instead of the standard 
    output. This file can be the same as one of the input files.

まさに!できます !私はそれについての手がかりを見ることができませんman sort-それは文書化されていない機能ですか?標準でポータブルですか?
グジェゴシWierzowiecki

@GrzegorzWierzowiecki:アップデートをご覧ください。
enzotib

素敵な答え :)。
グジェゴシWierzowiecki

1
要約sort -o <filename> <filename>すると、ファイルを所定の位置に安全にソートします。
フィアット

11

このsponge関数を使用できます。この関数は、最初に浸漬しstdin、次にファイルに書き込みます:

sort < f | sponge f

欠点はsponge、出力を一時的にメモリに保存することです。これは、大きなファイルでは問題になる可能性があります。それ以外の場合は、最初にファイルに書き込んでから元のファイルを上書きする必要があります。

しかし、他の回答で指摘されているように、プロセスの途中(たとえば、プロセスsponge)でマシンがクラッシュし、元のファイルと新しいファイルの両方を失う可能性があるため、インプレース変更は一般的に良いアイデアではありません。最初に別のファイルに書き込んでから、アトミックmv(移動)命令を使用することをお勧めします。


7

入力ファイルを出力ファイルで上書きするのは危険です。ファイルの書き込み中にプログラムまたはシステムがクラッシュすると、両方が失われるためです。

いくつかのプログラム(主にGNUバージョン)にはインプレースオプションがあります(-iperlおよびGNU sed、-oGNUソートなど)。データを一時ファイルに入れてから、所定の場所に移動することで機能します。そのようなオプションが用意されていないプログラムでは、コリン・ワトソンのspongeユーティリティ(に含まJoey Hessさんのmoreutilsは)任意のプログラム(例については、安全に仕事をしていません:私がすることはできますcut?場所にファイルを変更する ; どのように私はiconvのは、変換された入力ファイルを置き換えることができます出力?)。

同じ権限で元のファイルを再作成できないまれな場合にのみ、ファイルを所定の場所に上書きすることをお勧めします。この場合、元の入力をどこかに保存することをお勧めします。そして、入力のコピーを処理して、元のファイルに送信するだけです。

cp -p f ~/f.backup
sort <~/f.backup >|f
rm ~/f.backup # optional

1
sort -oGNU固有ではなく、特にファイルを所定の場所に配置するように設計されています。sort入力を完全に読み取る前に出力の書き込みを開始することはできません(メモリまたは一時ファイルを使用してデータを保存します)。そのため、入力をオーバーライドできるはずです。
ステファンシャゼル

そして実際には、GNU sortがPOSIXではないという1つのケースがあります。これはsort -mo file1 file1 file2、従来sortのsがその回避方法を知っているのに、動作が保証されていない(70年代のUnix V7で)
ステファンシャゼル

@JoelCross Odd、sort -ocoreutils 8.25で動作し、プロパティはマニュアルに記載されています(マージ時ではなく、ソート時のみであることに注意してください)。これを再現できる場合は、バグレポートを送信します(正確なコマンドライン、正確な入力ファイル、実行しているシステム、バイナリの入手方法を示します)。
ジル

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