需要 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”。一个或多个空格作为数组分隔符:

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

获取变量中的字符数:

${#delimiters}

添加一个:

$((${#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

相关内容