2017-08-19 27 views
0

'|'で区切られたフィールドを持つ 'echo'コマンド出力を出力したいのですが、すべての列に対して固定幅の同じ列に変換します。したがって、列の数は変わる可能性があります。幅は、すべての列に適用されるグローバルな設定にする必要があります。awk出力列の幅を固定

サンプル入力

1234|sdan:active:running|sdax:active:running|sdbh:active:running|sdcv:active:running|sddf:active:running|sddp:active:running|Total paths 6 : OK 
1235|sdc:active:running|sdm:active:running|sdw:active:running|sdbk:active:running|sdbu:active:running|sdce:active:running|Total paths 6 : OK 
1236|sdam:active:running|sdaw:active:running|sdbg:active:running|sdde:active:running|sdcu:active:running|sddo:active:running|Total paths 6 : OK 
+2

[ask]を参照してからもう一度やり直してください。 –

答えて

-1

awkを必要ですか?

cat input.txt | tr '|' ' ' | rev | column -t | rev 

あなたが本当にしたいのですが、集計魔法がrevcolumn -tで発生した場合awktrを置き換えることができます。

Credit

+0

ここで 'rev'の目的は何ですか?彼らが省略されても私は違いは見られません。 –

+0

diito 'cat'と最初のパイプ対' <'。また、 'column'は各フィールドを保持するのに十分な幅の列を作成しますが、OPが要求するように、すべての列をお互いに同じ幅にするわけではありません。 –

0

これは、すべてのライン上の各フィールドを変更するだけで行うのに十分に簡単です。次転写産物これを実行する方法を示しています。

pax> cat qq.awk 
BEGIN { OFS = FS = "|" } 
{ for (i = 1; i <= NF; i++) { 
     $i = sprintf("%-12s", $i) 
    } 
    print 
} 

pax> cat qq.input 
1234|sdan:active|sdcv:running|sddf:dead|sddp:active|3 paths:BAD 
1235|sdc:active|sdm:active|sdw:running|sdbk:running|4 paths:OK 
1236|sda:active|sdm:dead|2 paths:BAD 

pax> awk -f qq.awk qq.input 
1234  |sdan:active |sdcv:running|sddf:dead |sddp:active |3 paths:BAD 
1235  |sdc:active |sdm:active |sdw:running |sdbk:running|4 paths:OK 
1236  |sda:active |sdm:dead |2 paths:BAD 

sprintforループ内であり重要なことは、(ループは、すべて単一のフィールドを行い言った):

$i = sprintf("%-12s", $i); 

これは、コンテンツと、各フィールドを置き換え(少なくとも)その指定された幅に右に詰め込まれた、そのフィールドのスペース。

あなたはワンライナーではなく、きれいにフォーマットされたスクリプトを使用する場合は、あなたが使用することができます。

awk 'BEGIN{OFS=FS="|"}{for(i=1;i<=NF;i++){$i=sprintf("%-12s",$i)};print}' qq.input 
+0

ITYM 'for(i = 1; i <= NF; i ++)'。書かれているように、フルレコード($ 0)にはsprintfが適用されます(何もしません)。また、最終フィールド($ NF)は他のフィールドと同じ幅にフォーマットされません。また、末尾のセミコロンは無用です。 AwkはCではないので、配列であり、文字列とフィールドのインデックスは0ではなく1から始まり、ステートメントを終了するためにセミコロンは必要ありません。ちょうど改行。 –

+0

@Ed、良い点、私はそれを修正します。セミコロンは、私が頻繁に使用する傾向があるので、これらの答えのコードを読みやすいものにしますが、実際には*作業を行うためにすべて1行に入れてください。 – paxdiablo

0

awkは簡単ですが、それはsedで行うことができます:考える

width=12 
printf -v blanks '%*s' "$width" 
sed -rf <(echo "s/\|/${blanks}|/g; s/(.{${width}})[^|]*\|/\1|/g") input.txt 
0

$ cat file 
1234|sdan:active|sdax:active|sdbh:active|sdcv:active|sddf:active|sddp:active|Total paths 6 : OK 
1235|sdc:active|sdm:active|sdw:active|sdbk:active|sdbu:active|sdce:active|Total paths 6 : OK 
1236|sdam:active|sdaw:active|sdbg:active|sdde:active|sdcu:active|sddo:active|Total paths 6 : OK 

ここではすべてのフィールドを長めに印刷するawkがありますwの値、またはそのフィールド内の文字列の長さの:あなたがを介して実行したい場合は

$ awk 'BEGIN{OFS=FS="|"; w=11} 
    {for (i=1;i<=NF;i++) printf "%-*s%s", w, substr($i,1,w), i==NF ? ORS : OFS} 
    ' file 
1234  |sdan:active|sdax:active|sdbh:active|sdcv:active|sddf:active|sddp:active|Total paths 
1235  |sdc:active |sdm:active |sdw:active |sdbk:active|sdbu:active|sdce:active|Total paths 
1236  |sdam:active|sdaw:active|sdbg:active|sdde:active|sdcu:active|sddo:active|Total paths 

$ awk 'BEGIN{OFS=FS="|"; w=8} 
{for (i=1;i<=NF;i++) printf "%-*s%s", w, $i, i==NF ? ORS : OFS}' file 
1234 |sdan:active|sdax:active|sdbh:active|sdcv:active|sddf:active|sddp:active|Total paths 6 : OK 
1235 |sdc:active|sdm:active|sdw:active|sdbk:active|sdbu:active|sdce:active|Total paths 6 : OK 
1236 |sdam:active|sdaw:active|sdbg:active|sdde:active|sdcu:active|sddo:active|Total paths 6 : OK 

あなたがその一定の幅に合わせて長いフィールドをカットしたい場合すべてのフィールドに収まる幅を取得し、その幅ですべてのフィールドを印刷します。

$ awk 'BEGIN{OFS=FS="|"} 
     NR==FNR {for (i=1;i<=NF;i++) w=length($i)+1>w ? length($i)+1 : w; next} 
       {for (i=1;i<=NF;i++) printf "%-*s%s", w, $i, i==NF ? ORS : OFS} 
    ' file file 
1234    |sdan:active  |sdax:active  |sdbh:active  |sdcv:active  |sddf:active  |sddp:active  |Total paths 6 : OK 
1235    |sdc:active   |sdm:active   |sdw:active   |sdbk:active  |sdbu:active  |sdce:active  |Total paths 6 : OK 
1236    |sdam:active  |sdaw:active  |sdbg:active  |sdde:active  |sdcu:active  |sddo:active  |Total paths 6 : OK 
関連する問題