이진수로 단어 목록 만들기

이진수로 단어 목록 만들기

다음과 같은 행렬이 있습니다.

입력하다:

A   B   C   D   E   F   G   H   I 
0   0   0   0   1   0   0   0   1
0   0   0   1   0   0   0   0   0  
0   0   0   1   0   0   0   0   0  
1   0   0   0   0   0   0   0   0  
1   0   1   0   0   0   1   0   0  
1   0   0   1   0   0   0   1   0  
1   0   0   0   1   1   1   0   0  

각 행의 값 1에 해당하는 문자 목록을 추출하고 싶습니다.

산출:

E,I 
D
D
A
A,C,G  
A,D,H  
A,E,F,G  

제목을 나누고 단어를 숫자와 일치시켜 보았지만 실패했습니다.

답변1

존재하다 awk:

NR == 1 { for(column=1; column <= NF; column++) values[column]=$column; }
NR > 1 { output=""
        for(column=1; column <= NF; column++)
                if($column) output=output ? output "," values[column] : values[column]
        print output }

답변2

또 하나는perl

$ perl -lane 'if($. == 1){ @h=@F }
              else{@i = grep {$F[$_]==1} (0..$#F); print join ",",@h[@i]}
             ' ip.txt
E,I
D
D
A
A,C,G
A,D,H
A,E,F,G
  • -a입력 줄을 공백으로 분할하는 옵션( @F배열 에서 사용 가능)
  • if($. == 1){ @h=@F }첫 번째 행에 제목이 있는 경우
  • @i = grep {$F[$_]==1} (0..$#F)항목이 다음과 같은 경우 색인 저장1
  • print join ",",@h[@i],헤더 배열의 해당 인덱스만 인쇄하려면 구분 기호로 사용하세요.

답변3

여전히 재미로 사용하는 버전은 다음과 같습니다 zsh.

{
   read -A a  &&
   while read -A b; do
     echo ${(j<,>)${(s<>)${(j<>)a:^b}//(?0|1)}}
   done
} < file
  • ${a:^b} 지퍼두 개의 배열이므로 A 0 B 0 C 0 D 0 E 1 F 0 G 0 H 0 I 1이 됩니다.
  • ${(j<>)...}연결된 요소 사이에 아무것도 없으므로 A0B0C0D0E1F0G0H0I1이 됩니다.
  • ${...//(?0|1)}EI가 되도록 ?0and를 제거합니다 .1
  • ${(s<>)...}문자당 하나의 요소로 구성된 배열을 얻기 위해 분할하지 않고: EI
  • ${(j<,>)...}가입 하시는 분들 ,-> E,I.

답변4

Perl 솔루션은 다음과 같습니다.

use strict;

my @header = split /\s+/, <>;
<>; ## Skip blank line
while (<>) {
    my @flags = split /\s+/;
    my @letters = ();
    for my $i (0 .. scalar @flags - 1) {
        push @letters, $header[$i] if $flags[$i];
    }

    print join(',', @letters), "\n";
}

헤더 열을 배열로 읽어온 다음 각 데이터 행에 대해 일치하는 데이터 열이 true로 평가되면 열 이름이 출력 배열에 복사됩니다. 그런 다음 쉼표로 구분된 열 이름을 인쇄합니다.

관련 정보