$ echo "a b" | awk '{print $0; $1="1"; print $0}' ab 1 b
次のような書式設定された出力を受け取りたいです。
a b
1 b
それを行う簡単な方法はありますか(IFS、OFSの変更なし)? 大きなテーブルの列を変更していますが、その後見苦しくなります。各列を再フォーマットしたくありません。
ありがとう。
おそらく最善の策は、出力を後処理することです。おそらく次のような単純なものです。
$ ... | awk ... | 列 -t
動作します。(「各列をフォーマットしたくない」が「各行を再フォーマットしたくない」、たとえば「後処理をしたくない」という意味でない限り。その場合、「どうして? ")
考えられる答えの 1 つ (固定数の列を想定):
echo "a b" | awk '{print $0; $1="1"; printf("%s\t%s\n", $1, $2)}'
もう 1 つの考えられる答え (OFS の変更を避ける正当な理由がないと仮定すると、それが OFS を持つことの全体的なポイントです!):
echo "a b" | awk 'BEGIN { OFS="\t" } {print $0; $1="1"; print $0}'
この 2 番目の方法には、テキスト ファイルの列数に関係なく機能するという利点があります。
追加するために編集:
OFSの使用に対するあなたの嫌悪感が奇妙だと思う理由を説明すると、フォーマットの変更を取得している理由はすべてOFSのためです。出力フィールド区切り文字 (OFS) は、デフォルトでは単一のスペースです。最初に $0 を印刷したときは、何の変更も加えていなかったので、$0 は変更されていない行でした。レコードの 1 つを変更することで、個々のフィールドから $0 を再構築することで、Awk が行を再評価しました。もちろん、これを再構築する際に、Awk はフィールド間に OFS を挿入しました。それが本来の役割だからです。関連するマニュアルページ (man gawk) からの引用:
既存のフィールドに値を割り当てると、
$0
参照時にレコード全体が再構築されます。同様に、値を割り当てる$0
と、レコードが再分割され、フィールドに新しい値が作成されます。
最初のプリントと 2 番目のプリントでフィールドの扱いが異なることに少し矛盾があることに同意しますが、それが言語のやり方です。OFS は、実際に文字列を変更し、実際にフィールドを計算して再構築するまで挿入されません。
さらに編集して追加します:
これらを見てください:
$ awk 'BEGIN { printf("|%s|\n", OFS) }'
| |
$ awk 'BEGIN { OFS="\t" ; printf("|%s|\n", OFS) }'
| |
$
最初の例での Awk の動作はより明確になり、OFS や printf などが実際に必要な理由を理解していますか?
置換を使用することもできます
$ echo "a b" | awk '{print $0; gsub("^[^ \t]","1"); print $0}'
a b
1 b