私はawk
を学んでおり、ファイルへの変更を保存するために-i
オプションを使用するsed
と同様に、ファイルに変更を書き込むオプションがあるかどうかを知りたいです。
リダイレクトを使用して変更を書き込むことができることを理解しています。ただし、awk
にはそれを行うオプションがありますか?
最新の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
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 へのリンクがあります。
これは機能しません:
someprocess < file > file
シェルはリダイレクトを実行しbefore制御をプロセスに引き渡します( redirections )。 >
リダイレクトは、ファイルのサイズをゼロに切り捨てます( 出力のリダイレクト )。したがって、someprocessが起動され、ファイルから読み取りを行うまでに、読み取り対象のデータはありません。
別の方法は、sponge
を使用することです。
awk '{print $0}' your_file | sponge your_file
'{print $0}'
をawkスクリプトに、your_file
をその場で編集するファイルの名前に置き換えます。
sponge
は、ファイルに保存する前に入力を完全に吸収します。
ほんの少しハックが動作します
echo "$(awk '{awk code}' file)" > file
フォローは機能しません
echo $(awk '{awk code}' file) > file
これは動作するはずです
echo "$(awk '{awk code}' file)" > file
awk '{awk code}' file | tee file
tee
コマンドは、|
によりawk
コマンドが終了した後に実行されます。
一時ファイルを作成せず、バージョンで使用可能なawkのみのソリューションが必要な場合!=(gawk 4.1.0):
awk '{a[b++]=$0} END {for(c=0;c<=b;c++)print a[c]>ARGV[1]}' file