sedを使用してあるファイルの内容を別のファイルにコピーする

sedを使用してあるファイルの内容を別のファイルにコピーする

Alma Linux 8では、sedを使用してあるファイルのすべてのテキストを別のファイルにコピーしたいと思います。たとえば、最初のファイルold.txtは次のようになります。

192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5 
...

別のファイルはnew.txt次のとおりです。

192.168.0.1
192.168.0.2
192.168.0.3

アイテムをコピーしたいが複製しませold.txtnew.txt。期待される出力new.txt:

192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5 

どうすればいいですか?

答え1

一意性制約を持つ単純な順序を除いて、何も必要ありません。

sort -u old.txt new.txt >new.txt.tmp &&
     mv -f new.txt.tmp new.txt
rm -f new.txt.tmp

私は見たPOSIXsort能力を定義する入力ファイルに直接書き込むしたがって、これも実行できますが、エラーが発生したときにどれほど強力であるかをテストしていません(以前のバージョンでは、失われることなくオリジナルを保持したり、新しいバージョンに置き換えることができます)。

sort -o new.txt -u old.txt new.txt

またはを使用できますawk。このバージョンは、最初のファイルから始まり、ファイルの行の順序を変更せずに維持し、後続のファイルにのみ新しい行を追加します。

awk '
    FNR<NR && h[$0] { next }    # Skip seen lines in secondary files
    { h[$0]=1; print }          # Record the line and output it
' new.txt old.txt

説明を追加できるように行に分割しました。これを削除すると、1行に縮小することができますが、通常は読みやすいコードを書く方が良いでしょう。意図的に最初のファイルは削除しませんnew.txt

awk '! h[$0]++' new.txt old.txt

これは、表示される各行の連想配列値を増やしますが、値が0(未設定)の場合にのみ印刷します。

答え2

sort他の回答に従ってコマンドを使用できますが、出力ファイルに明示的に言及し、所定の位置でソートを実行できます(中間ファイルなし)。

sort -u -o new.txt old.txt new.txt  

可能な方法の1つawk

awk -i inplace '{z[$0]=1} END{for( i in z) print i}' new.txt old.txt

入力ファイルのいずれかまたは両方が非常に長い場合、多くのメモリを「食べる」ことができます。inplace出力を維持しますnew.txt

答え3

これは実際には機能しませんが、使用sedする必要があり、GNUになる場合は、次のことができます。sedsedsed

sed -E '
  :1; $!{N;b1}
  :2; s/^((.*)$(.|\n)*)\n\2$/\1/m; t2
  ' new.txt old.txt

どこ:

  • :1; $!{N;b1}フル入力(パターンスペースの2つのファイル)をループにロードします。
  • :2; s/^((.*)$(.|\n)*)\n\1$/\1/m; t2ループ内のこのパターン空間から重複行を削除します。

現在の場所で変更するには、new.txt次の操作を行います。

sed -nE '
  :1; $!{N;b1}
  :2; s/^((.*)$(.|\n)*)\n\1$/\1/m; t2
  w new.txt
  ' new.txt old.txt

答え4

使用幸せ(以前のPerl_6)

~$ raku -e '.put for lines.unique;'  old.txt new.txt  > tmp.txt

Rakuはコマンドラインからファイルを読み取るためにジョブルーチンを使用しますlines。したがって、2つのファイルを読み取り、1つ>のファイルにリダイレクトできますtmp.txt。その後、結果が確認されたらtmp.txtファイルを再コピーできますnew.txt

Rakuは「内部」編集を行いません(つまり、-iRakuにはPerlのコマンドラインフラグと同等の機能はありません)。

入力例old.txt:

192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5 

入力例new.txt:

192.168.0.1
192.168.0.2
192.168.0.3

出力例tmp.txt:

192.168.0.1
192.168.0.2
192.168.0.3
192.168.0.4
192.168.0.5 

Rakuルーチンの1つの利点は、パラメータuniqueを使用することですas。つまり、入力ラインの一部のみが比較に使用されますunique。これらのオプションを使用すると、(たとえば)フルパスから一意のファイル名を回復し、別のディレクトリから重複した名前を削除できます。詳細については、以下の最初のSOリンクを参照してください。

https://unix.stackexchange.com/a/720574/227738
https://docs.raku.org/routine/unique
https://raku.org

関連情報