次のパターンに転置/回転するには、AwkまたはUnixスクリプトが必要です。

次のパターンに転置/回転するには、AwkまたはUnixスクリプトが必要です。

ファイルには次の形式のデータが含まれます(最初の行はヘッダーです)。

N ; A ; B 
=========
1 ; 01;02 
2; 02;02 

最初の列に基づいて、次の出力が予想されます。 N列は同じままですが、他の列は増やしてC、D、Eなどにすることができ、その値をキャプチャできます。

1;A;01 
2;A;02
1:B;02
2;B;02 

どうすればいいですか?

答え1

以下はPythonを使ったコードスニペットです。

パスワード:

# read in the data
with open('data_file', 'rU') as f:
    # read in the header
    header = [x.strip() for x in f.readline().split(';')]

    # drop the ======
    dump_marker = f.readline()

    # get the rest of the data
    data = [[x.strip() for x in line.split(';')] for line in f.readlines()]

# print the data in new format
for i, col in enumerate(header[1:]):
    for line in data:
        print("{};{};{}".format(line[0], col, line[i+1]))

データファイル:

N ; A ; B
=========
1 ; 01;02
2 ; 02;02

結果:

1;A;01
2;A;02
1;B;02
2;B;02

答え2

Bashでは、組み込みコマンドtailと以下を使用してこれを実行できますcut

#! /bin/bash
# Get header line
header=$( head -n 1 data_file )
# Make a variable with all delimiters (2)
delimiters=${header//[^;]/}
# Make an array with all column names
declare -a colnames=( ${header//;/ } )
# For all columns one at the time...
for C in $(seq 2 $((${#delimiters}+1)) ) ; do
    index=$((C-1))
    # Skip first 3 lines of data_file
    tail --lines=+3 data_file | cut -d\; -f1,$C | while read; do
        # Replace first ';' with column name
        line=${REPLY/;/;${colnames[$index]};}
        # Remove all spaces and print
        echo ${line// /}
    done
done

説明する:

ファイルの最初の行を変数に入れます(以降は変更可能)。

header=$( head -n 1 data_file )

変数からセミコロン区切り文字を除くすべての文字を削除します。

delimiters=${header//[^;]/}

変数$ delimitersには ';;'が含まれます。

すべての ';'を空白に置き換えます。 「NA B」が表示されます。配列区切り文字として使用される1つ以上のスペース:

declare -a colnames=( ${header//;/ } )

変数の文字数を取得します。

${#delimiters}

1つを追加してください:

$((${#delimiters}+1))

それから

$(seq 2 $((${#delimiters}+1)) )

同じ:

$(seq 2 3 )

変数のインデックスは0..nで始まり、-1で始まる列名を探します。

index=$((C-1))

ファイルを読み、最初の3行をスキップし、列番号のみを表示し$C、その行を変数として読み込みます$REPLY

tail --lines=+3 data_file | cut -d\; -f1,$C | while read; do

答え3

そして使用された解決策は次のとおりですawk

awk -F';' '{ gsub(/ /,"");}
           NR==1 { cols = split($0, col); }
           NR > 2 { for (i = 2; i <= cols; i++) {
                        data[col[i]";"$1] = $1";"col[i]";"$i; }
                  }
           END { no = asorti(data, sorted);
                 for (i = 1; i <= no; i++) {
                     print data[sorted[i]]; }
               }' input

関連情報