動的列幅と空のフィールドを使用した出力の解析

動的列幅と空のフィールドを使用した出力の解析

ドライバーlist次の例に示すように、ファイルリストを印刷するサブコマンドがあります。

gdrive list

出力:

Id                                  Name                      Type   Size     Created
1sV3_a1ySV0-jbLxhA8NIEts1KU_aWa-5   info.pdf                  bin    10.0 B   2018-08-27 20:26:20
1h-j3B5OLryp6HkeyTsd9PJaAtKK_GYyl   2018-12-ss-scalettapass   dir             2018-08-27 20:26:19

同様のツールを使用してこの出力を解析しようとしましたが、成功しませんでしawksed

問題は、サイズ列の空の「フィールド」と列の動的幅にあります。

この出力を解析する方法を知っている人はいますか?

ベストアンサー1

awkは固定幅データを処理できます。まず、列の幅を決定する必要があります。

fieldwidths=$(head -n 1 file | grep -Po '\S+\s*' | awk '{printf "%d ", length($0)}')

値は"36 26 7 9 7 "- 最後のフィールドが7文字より大きいです。任意に70文字に設定しました。

fieldwidths=${fieldwidths/% /0}

それでは、データを読み込んでCSVに変換してみましょう。

awk -v FIELDWIDTHS="$fieldwidths" '{
    for (i=1; i<=NF; i++) {
        val = $i
        sub(/ *$/, "", val)
        gsub(/"/, "\"\"", val)
        printf "%s\"%s\"", (i==1 ? "" : ","), val
    }
    print ""
}' file

出力:

"Id","Name","Type","Size","Created"
"1sV3_a1ySV0-jbLxhA8NIEts1KU_aWa-5","info.pdf","bin","10.0 B","2018-08-27 20:26:20"
"1h-j3B5OLryp6HkeyTsd9PJaAtKK_GYyl","2018-12-ss-scalettapass","dir","","2018-08-27 20:26:19"

Perlと同じ機能を持っています。

perl -lne '
    if ($. == 1) {
        @head = ( /(\S+\s*)/g );
        pop @head;
        $patt = "^";
        $patt .= "(.{" . length($_) . "})" for @head;
        $patt .= "(.*)\$";
    }
    print join ",", map {s/"/""/g; s/\s+$//; qq("$_")} (/$patt/o);
' file

おすすめ記事