열에서 데이터 행렬로 awk

열에서 데이터 행렬로 awk

awk저는 이 테이블에서 다음과 같은 솔루션을 찾고 있습니다 (열 1의 x 이름, 길이가 다른 열 2, ";"으로 구분).

데이터프레임.txt:

name1 1;2;4;8
name2 4;5;7
name3 8
name4 11;12
namex 20;21

1존재와 부재를 포함하는 이 행렬에 0:

매트릭스.txt:

        1 2 4 5 7 8 11 12 20 21
name1   1 1 1 0 0 1 0  0  0  0 
name2   0 0 1 1 1 0 0  0  0  0
name3   0 0 0 0 0 1 0  0  0  0
name4   0 0 0 0 0 0 1  1  0  0
namex   0 0 0 0 0 0 0  0  1  1

답변1

Awk해결책:

awk 'BEGIN{
         h = "1 2 3 4 5 6 7 8 11 12 20 21";
         len = split(h, head);
         print "\t\t" h
     }
     {
         printf "%s\t", $1;
         for (i = 1; i <= len; i++)
             printf "%s%d", (i == 1? "" : OFS), ($2 ~ "\\<" head[i] "\\>");
         print "" 
     }' file
  • h = "1 2 3 4 5 6 7 8 11 12 20 21"-머리글철사
  • len = split(h, head)- h행을 배열로 분할합니다 head. 여기서 index는 시작 위치에서 정렬된 위치 1이고 value는 분할하여 얻은 키 값이며 len배열 크기를 포함합니다 .
  • print "\t\t" h- 인쇄머리글선행 탭이 있는 줄
  • printf "%s\t", $1;-첫 번째 필드를 인쇄합니다.$1
  • for (i = 1; i <= len; i++)- 반복적인 head프로젝트
    • $2 ~ "\\<" head[i] "\\>"- 두 번째 필드에 $2현재 액세스된 항목이 포함되어 있는지 확인head[i]

산출:

        1 2 3 4 5 6 7 8 11 12 20 21
name1   1 1 0 1 0 0 0 1 0 0 0 0
name2   0 0 0 1 1 0 1 0 0 0 0 0
name3   0 0 0 0 0 0 0 1 0 0 0 0
name4   0 0 0 0 0 0 0 0 1 1 0 0
namex   0 0 0 0 0 0 0 0 0 0 1 1

답변2

또 다른 awk방법은 먼저 헤더를 직접 생성한 다음1배열의 각 키는 head현재 입력 행에 존재합니다. 그렇지 않은 경우0존재하지 않는 경우.

우리는 숫자의 왼쪽 가장자리에 있는 빈 문자열과 일치하는 숫자를 grep가져오곤 했습니다 ( 왼쪽과 오른쪽에 사용한 것과 동일).-o\b\<awk

awk 'NR==FNR { !head[$1]++; next } 
    { printf $1; for (x in head) { printf (x?FS:"") ($0 ~ "\\<" x "\\>") }; print ""
}' <(grep -o '\b[0-9]\+' infile) infile

출력은 다음과 같습니다

name1 1 1 1 0 0 1 0 0 0 0
name2 0 0 1 1 1 0 0 0 0 0
name3 0 0 0 0 0 1 0 0 0 0
name4 0 0 0 0 0 0 1 1 0 0
namex 0 0 0 0 0 0 0 0 1 1

헤더를 생성하여 입력 파일의 첫 번째 줄에 삽입하면 awk간단합니다.

awk 'NR==1{ split($0, head); next }
    { printf $1; for (x in head){ printf (x?FS:"") ($2 ~ "\\<" head[x] "\\>" ) }; 
print "" }' infile

관련 정보