タブ区切りファイルの外観の変更

タブ区切りファイルの外観の変更

次のファイルがあります。

 Time   Flag
 0.65   5.885581e-01
 0.56   5.847484e-01
 0.58   5.278409e-01
 0.57   1.140746e+00
 1.00   0
 0.00   0
 1.00   1
 0.00   0

しかし、それは私が書くときに何かを変えるのを忘れてしまったからです。したがって、タイミングの半分はフラグ列で終わり、フラグの半分は時間列で終わる。やらなければならなかった

 Time Flag
 0.65   1
 0.59   0
 0.56   0
 0.58   0
 0.58   1
 0.53   1
 0.57   0
 1.14   0

したがって、この小さな例では、最初の4行が最初の列になるはずです。最後の4行は2番目の列にする必要があります。各列の要素の半分は、元のファイルで正しい形式(交互)で指定されています。形を変えて型を変える最も簡単な方法は何ですか?

答え1

$ awk 'NR > 1 { d[++n] = $1; d[++n] = $2 } END { print "Time", "Flag"; for (i = 1; 2*i <= n; ++i) printf "%.2f%s%d%s", d[i], OFS, d[n/2 + i], ORS }' file
Time Flag
0.65 1
0.59 0
0.56 0
0.58 0
0.58 1
0.53 1
0.57 0
1.14 0

このawkコードは、すべてのデータを行単位で読み取り、配列の連続要素として読み取りますd(ヘッダーをスキップ)。

ENDブロックからヘッダーが印刷され、次に1から配列の長さiの半分まで繰り返し、dインデックス(時間値)の値とマーク(フラグ値)iの値を印刷します。n/2 + i時間値が小数点以下の2桁の浮動小数点値で印刷され、フラグ値が整数で印刷されるように出力形式を完了します。

OFS変数にはORSデフォルトの出力フィールドとレコード区切り文字があります(デフォルトはスペースと改行)。タブ区切り出力の場合awk -v OFS='\t' '{ ... }' file

ちなみに、このawkコードはスタンドアロンスクリプトとして機能します。

#!/usr/bin/awk -f

NR > 1 {
    d[++n] = $1
    d[++n] = $2
}

END {
    print "Time", "Flag"

    for (i = 1; 2*i <= n; ++i)
        printf "%.2f%s%d%s", d[i], OFS, d[n/2 + i], ORS
}

答え2

OPは、問題がファイルを半分に分割し、各半分を回復して再結合する必要があることを示していませんが、その知識なしにこれを行う方法を知りたいです。

私は本当に好きですcsvkit特にGoCSV宣言的パイプライン処理用。

変換/設定

最初のステップは、固定幅のサンプルデータをCSVに変換することです。 csvkitを使用すると、列の幅パターンを指定できます。

スキーマ.csv

column,start,length
Time,0,4
Flag,7,13

次にCSVに変換します。

in2csv -s schema.csv input.txt > input.csv

分離と転置

入力をフラグと時間というカテゴリ別に分けたい。次に、各カテゴリに対して単一行CSVセットを作成します(次のステップの転置のため)。

gocsv filter -c 2 --regex "^[01]$" input.csv | 
gocsv split --max-rows 1 --filename-base flags

補完的な時間には同じパターンが使用されます--exclude

gocsv filter -c 2 --regex "^[01]$" --exclude input.csv | 
gocsv split --max-rows 1 --filename-base times

これにより、次のファイルセットが作成されます。

ls flags-*.csv                                     
flags-1.csv  flags-2.csv  flags-3.csv  flags-4.csv

それぞれは次のとおりです。

ロゴ-1.csv

Time,Flag
1.00,0

または:

times-4.csv

Time,Flag
0.57,1.140746e+00

ヘッダーはTime,Flagそれほど重要ではありませんが、ヘッダーが存在し、転置された構造に影響を与えるかどうかを見ることが重要です。

各ファイルに対して転置を繰り返し、2番目の列を選択し(誤ったヘッダーが1列目になるため)、適切なヘッダーで終了します。

for FILE in flags-*; do 
  gocsv transpose $FILE | 
  gocsv select -c 2 | 
  gocsv cap --names Flag \
  > trans_$FILE; 
done

for FILE in times-*; do
  gocsv transpose $FILE |
  gocsv select -c 2 |
  gocsv cap --names Time \
  > trans_$FILE;
done

柱に積もった

フラグと時間を独自の列に積み重ねます。

gocsv stack trans_flags*  > col_flag.csv

gocsv stack trans_times*  > col_time.csv

それから一緒に圧縮します(私はただ使用します)。csvlookもっときれいなMarkdownテーブルがありますが、数値も正規化するからです! ):

gocsv zip col_time.csv col_flag.csv > output.csv
csvlook output.csv
時間 バナー
0.650… 1
0.589… 0
0.560… 0
0.585… 0
0.580… 1
0.528… 1
0.570… 0
1.141… 0

これはかわいいです。

しかし、最後のステップは、GoCSVに組み込まれた(私にとって新しい)SPRIGテンプレートとround関数を使用して、浮動小数点、整数、および科学的表記を整理することです。元の列に基づいて新しい列を追加し、新しい列または書式設定された列のみを選択します。

cat output.csv |
gocsv add -n Time -t "{{round .Time 2}}" |
gocsv add -n Flag -t "{{round .Flag 0}}" |
gocsv select -c 3- |
gocsv tsv

私達は次を得ました:

Time    Flag
0.65    1
0.59    0
0.56    0
0.58    0
0.58    1
0.53    1
0.57    0
1.14    0

関連情報