一意の並べ替え:出力を同じファイルにリダイレクトします


14

パイプ出力を処理された同じファイルに保存する簡単な方法はありますか?たとえば、これは私が実際にやっていることです

$ cat filename | sort | uniq > result
$ rm -f filename
$ mv result filename

1行でそれを行う方法があるかどうか疑問に思っていました(&&を使用してこれらのコマンドを追加しないでください)

これは方法ではありませんが、アイデアを得るために

$ cat filename | sort | uniq > filename

2
echo $(cat filename | sort | uniq > result) > filenameか何か ?ただ通り過ぎて、私はそれを試す時間がありません。
MrVaykadji 14

回答:


18

moreutilsパッケージspongeから使用できます。

LC_ALL=C sort -u filename | sponge filename

また、並べ替えの際に一意の行を選択できるオプションがあるためuniq、にパイプする必要もありません。sort-u

注GNUシステム上のUTF-8ロケールを持つこと、sort -uまたはsort | uniqあなたのユニークなラインを与えるが、現在のロケールでのソート同じ行のシーケンスから最初はなかったです。

$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=en_US.utf8 sort | LC_ALL=en_US.utf8 uniq

あなただけを与えた。ロケールをCに変更すると、バイト値に基づいてソート順が強制されます。

$ export LC_ALL=C
$ printf '%b\n' '\U2460' '\U2461' | LC_ALL=C sort | LC_ALL=C uniq


12

catおよびuniqなどの追加のコマンドは必要ありません。また、rmコマンドとmvコマンドを使用してファイル名を削除および名前変更する必要もありません。単純なコマンドを使用してください。

sort -u filename -o filename


 -u, --unique
        with -c, check for strict ordering; without -c, output only  the
        first of an equal run

 -o, --output=FILE
        write result to FILE instead of standard output

それがどのように働きますか?

sortコマンドはファイル名をソートし、-uオプションを使用して、重複した行を削除します。次に、with -oオプションは、インプレースメソッドを使用して同じファイルに出力を書き込みます。


3
実行中にシステムがクラッシュするsortと、元のファイルが失われます。
クオングルム14

@Gnoucだから、これは不運の終わりです!! : '(
αғsнιη

1
ありがとう!この例では、特に「並べ替え」を使用して、それを行う必要があります。しかし、私は一般的なケースを考えていました。@Gnouc、ハハ、それがあなたに起こらなかったと思う方法はありませんよね?
whitenoisedb 14

3

実際に同じファイルの読み取りと書き込みを同時に行うため、提案された例(下記)は機能しません。

$ cat filename | sort | uniq > filename

パイプまたはリダイレクトのアイデアは、各パイプまたはリダイレクトの左右のコマンドが同時に並行して実行されるというものです。右側のコマンドは、左側のコマンドがまだ実行されている間に、左側のコマンドから引き渡された情報を処理します。

シナリオを機能させるには、ファイルに書き込むコマンドを開始する前に、ファイルから読み取るコマンドを終了する必要があります。これが機能するためには、最初に出力を一時的な場所にリダイレクトし、それが終了したら、一時的な場所からファイルに出力を戻す必要があります。

これを行うためのより良い方法は、基本的に前の例のように、一時ファイルにリダイレクトしてから元のファイルに名前を変更することです(移動すると既存のターゲットが削除されるため、最初にファイルを削除する必要はありません) 。

$ cat filename | sort | uniq > result
$ mv -f result filename

また、文字列変数に保存することもできます。ただし、データが十分に小さく、すべてが一度にメモリに収まる場合にのみ機能します。


誰かが提案された編集で発表したように、あなたはcat filename | sortちょうどに変更することができますsort filename- catここでは不要です。
thomasrutter 14

以下の私の例は、それを行う方法ではありませんでした。説明をありがとう。catこの場合は不要かもしれませんが、リダイレクト部分に焦点を合わせていました。
whitenoisedb 14

1
以下の例が機能しない理由を説明ていました。あなたはそれがうまくいかないことを知っていたことを知っています。
thomasrutter 14

明確にしてくれてありがとう!実際、私は実際に何が起こっているのか知りませんでした。
whitenoisedb 14

2

tee次のコマンドを使用できます。

sort -u filename | tee filename > /dev/null

このteeコマンドは、標準入力から読み取り、標準出力ファイルに書き込みます。


2
これは私には機能しません。
pjvandehaar


これ私にとってうまくいきます。たとえば、ファイルの最後に行を移動するには:(cat ~/file | grep -v 3662 ; printentry 3662) | tee ~/file > /dev/nullworks。あなただけの場合は、元の記事のように、これは動作しません> ~/fileなしtee。ここでsort -o file、Tee は同じパイプを継続せずに名前付きファイルに書き込みます。
ジョシュアゴールドバーグ

待って、ごめんなさい! @Stevenからのリンクで説明されているように、これは予想外にデータを失うことを経験的に見てきました。9行に番号1..9のファイルを作成します。以下は数回動作しますが、ファイルからすべてのデータを時々削除します:(cat x | grep -v 7 ; echo 7) | tee x > /dev/null; cat x 一時ファイルmvまたは@Stevenのリンクからのソリューションをお勧めします。
ジョシュアゴールドバーグ

@JoshuaGoldbergこのページで私の答えを見ましたか?
スティーブンペニー

0

ExモードでVimを使用できます:

ex -sc 'sort u|x' filename
  1. sort u ユニークな並べ替え

  2. x 変更が行われた場合(書き込みがあった場合)に書き込み、終了する

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