web-dev-qa-db-ja.com

awkを使用して変更を所定の場所に保存する

私はawkを学んでおり、ファイルへの変更を保存するために-iオプションを使用するsedと同様に、ファイルに変更を書き込むオプションがあるかどうかを知りたいです。

リダイレクトを使用して変更を書き込むことができることを理解しています。ただし、awkにはそれを行うオプションがありますか?

114
Deano

最新のGNU Awk( 4.1.0リリース済み )には、 "inplace"ファイル編集 のオプションがあります:

[...]新しい機能を使用して構築された「インプレース」拡張機能は、GNU "sed -i"機能をシミュレートするために使用できます。 [...]

使用例:

$ gawk -i inplace '{ gsub(/foo/, "bar") }; { print }' file1 file2 file3

バックアップを保持するには:

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{ gsub(/foo/, "bar") }
> { print }' file1 file2 file3
106
lind

GNU awk 4.1.0以降がある場合を除き...

Sedの-iオプションのようなオプションはありませんので、代わりに:

$ awk '{print $0}' file > tmp && mv tmp file

注:-iは魔法ではありません。また、一時ファイルsedを作成するだけで処理します。


GNU awk 4.1.0 ...の時点で

GNU awkは、バージョン4.1.0でこの機能を追加しました(2013年10月5日リリース)。リリースノートに記載されている-iオプションを指定するほど単純ではありません。

新しい-iオプション(xgawkから)は、awkライブラリファイルのロードに使用されます。これは、最初の非オプション引数がスクリプトとして扱われるという点で-fとは異なります。

バンドルされているinplace.awkインクルードファイルを使用して、次のように拡張機能を適切に呼び出す必要があります。

$ cat file
123 abc
456 def
789 hij

$ gawk -i inplace '{print $1}' file

$ cat file
123
456
789

変数INPLACE_SUFFIXを使用して、バックアップファイルの拡張子を指定できます。

$ gawk -i inplace -v INPLACE_SUFFIX=.bak '{print $1}' file

$ cat file
123
456
789

$ cat file.bak
123 abc
456 def
789 hij

この機能が追加されたことを嬉しく思いますが、言語の簡潔さからパワーが得られ、-i inplaceが8文字長すぎるimo

公式のWordの manual へのリンクがあります。

117
Chris Seymour

@ Sudo_O に権利がある answer

これは機能しません:

someprocess < file > file

シェルはリダイレクトを実行しbefore制御をプロセスに引き渡します( redirections )。 >リダイレクトは、ファイルのサイズをゼロに切り捨てます( 出力のリダイレクト )。したがって、someprocessが起動され、ファイルから読み取りを行うまでに、読み取り対象のデータはありません。

12
glenn jackman

別の方法は、spongeを使用することです。

awk '{print $0}' your_file | sponge your_file

'{print $0}'をawkスクリプトに、your_fileをその場で編集するファイルの名前に置き換えます。

spongeは、ファイルに保存する前に入力を完全に吸収します。

11
Codoscope

ほんの少しハックが動作します

echo "$(awk '{awk code}' file)" > file
11
Yuri G.

フォローは機能しません

echo $(awk '{awk code}' file) > file

これは動作するはずです

echo "$(awk '{awk code}' file)" > file
5
Flowmix Leonsio

ティーを使用する

 awk '{awk code}' file | tee file

teeコマンドは、|によりawkコマンドが終了した後に実行されます。

4
shaiki siegal

一時ファイルを作成せず、バージョンで使用可能なawkのみのソリューションが必要な場合!=(gawk 4.1.0):

awk '{a[b++]=$0} END {for(c=0;c<=b;c++)print a[c]>ARGV[1]}' file
3
Hawk