다음 패턴으로 전치/회전하려면 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

관련 정보