하나의 열(긴)을 다양한 길이의 여러 열(짧은)로 변환

하나의 열(긴)을 다양한 길이의 여러 열(짧은)로 변환

하나의 데이터 열(즉, 행당 하나의 데이터 값)을 포함하는 파일이 있습니다. 나는 이 데이터를 여러 가지로 해석합니다.데이터세트; 데이터 세트는 NA하나 이상의 행으로 구분됩니다. 데이터 세트의 길이는 다양합니다. 이를 다중 열 형식으로 변환하고 싶습니다. 여기서 각 데이터 세트는 입력 파일에 나타나는 것과 동일한 순서로 열에 있습니다.

예를 들어 다음 파일이 있습니다(실제로 이 파일에는 더 많은 데이터가 포함되어 있습니다).

NA
4
3
5
7
8
3
NA
NA
NA
3
4
5
2
NA
2 
7
4
6
9
NA

내 예상 결과는 다음과 같습니다.

4 3 2
3 4 7
5 5 4
7 2 6
8 . 9
3

8과 9 사이의 점은 실제로 필요하지 않지만 공백으로 대체할 수 있습니다.

답변1

awk각 데이터 세트(데이터가 NA행 사이에 있음)를 별도의 파일로 분할하고 NA행을 건너뛴 다음 paste함께 넣을 수 있습니다 .

awk '/^NA$/ && !NA{N++; NA=1; next} !/^NA$/{print >"file"N; NA=0}
    END{system("paste file*")}' inile.txt

NA플래그는 파일을 순차적으로 생성하는 데 사용되며, 아래에서 사용할 수 있습니다.

awk '/^NA$/{N++; next} !/^NA$/{print >"file"N}
    END{system("paste file*")}' inile.txt

출력은 다음과 같습니다

4 3 2
3 4 7
5 5 4
7 2 6
8   9
3

답변2

이 출력 형식은 나에게 적합하지 않습니다. 나는 이것이 전혀 실용적이지 않다고 생각합니다.

어쨌든, 한 줄에 작성하고 다음과 같이 바꾸십시오(또는 더 나은 방법은 한 줄에 유지하는 것입니다).

tr '\n' ' ' < example | tr 'N' '\n' | sed 's/^A //; /^$/d'

주어진

4 3 5 7 8 3 
3 4 5 2 
2 7 4 6 9

답변3

쉘에서 변환하는 것은 고통스럽습니다. 다음은 Perl의 짧은 대답입니다.배열::전치::비정형CPAN에서

perl -MArray::Transpose::Ragged=transpose_ragged -lnE '
        if (/NA/) { $n++; next }      # next row
        push @{$data[$n]}, $_;        # creating the 2D matrix of data
    } END {
        say join "\t", @$_ for transpose_ragged [grep {defined} @data];
' file

또 다른 접근 방식은 다음과 같습니다. 이전 파이프라인은 gawk기본적으로 @n.caillou의 답변과 동일하며 awk 코드가 바뀌었습니다.

paste -sd " " file | sed 's/NA/\n/g' | sed '/^ *$/d' | gawk '
    {
        for (i=1; i<=NF; i++) data[FNR][i] = $i
        if (NF > max) max = NF
    }
    END {
        for (i=1; i<=max; i++) {
            for (j=1; j<=NR; j++) printf "%s\t", data[j][i]
            print ""
        }
    }
'

GNU awk를 사용하여 다차원 배열 처리

답변4

이것GNU 데이터 혼합버전 1.1.1이 필요합니다. 버전 1.0.7에서는 제대로 작동하지 않습니다.

#!/bin/bash

tr '\n' ' ' < input.txt |
sed 's/\s*NA\s*/\n/g;' |
sed '/^$/d'  |
datamash --no-strict --filler="." -W -t' ' transpose

설명하다

  1. tr '\n' ' ' < input.txt- 모든 줄 바꿈을 공백으로 바꿉니다. 즉, 모든 행을 하나의 행으로 연결합니다.
  2. sed 's/\s*NA\s*/\n/g;'- 모든 "NA"와 인접한 공백을 개행 문자로 바꿉니다. 즉, 큰 줄을 여러 행으로 나누고, 각 행은 가로로 쓰여진 미래 열입니다.
  3. sed '/^$/d'- 빈 줄을 모두 제거합니다.
  4. datamash --no-strict --filler="." -W -t' ' transpose
    • --no-strict- 필드 수가 다른 행 허용
    • --filler="."- 누락된 값을 포인트로 채웁니다. 공간으로 변경될 수 있습니다.
    • -W- 공백(하나 이상의 공백 및/또는 탭)을 입력 필드 구분 기호로 사용합니다.
    • -t' '- 출력 필드 구분 기호로 탭 대신 공백을 사용합니다.
    • transpose- 행을 열로 변환합니다.

입력하다

NA
4
3
5
7
8
3
NA
NA
NA
3
4
5
2
NA
2
7
4
6
9
NA

산출

4 3 2
3 4 7
5 5 4
7 2 6
8 . 9
3 . .

관련 정보