1

$ echo "a b" | awk '{print $0; $1="1"; print $0}' ab 1 b

次のような書式設定された出力を受け取りたいです。

 a       b
 1       b

それを行う簡単な方法はありますか(IFS、OFSの変更なし)? 大きなテーブルの列を変更していますが、その後見苦しくなります。各列を再フォーマットしたくありません。

ありがとう。

4

3 に答える 3

2

おそらく最善の策は、出力を後処理することです。おそらく次のような単純なものです。

$ ... | awk ... | 列 -t

動作します。(「各列をフォーマットしたくない」が「各行を再フォーマットしたくない」、たとえば「後処理をしたくない」という意味でない限り。その場合、「どうして? ")

于 2010-07-02T15:52:09.587 に答える
2

考えられる答えの 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 などが実際に必要な理由を理解していますか?

于 2010-07-02T16:03:43.577 に答える
1

置換を使用することもできます

$ echo "a       b" | awk '{print $0; gsub("^[^ \t]","1"); print $0}'
a       b
1       b
于 2010-07-03T01:07:39.740 に答える