awkを使用して同じ列数を識別する

awkを使用して同じ列数を識別する

各ファイルには6つの列が含まれています(行数は異なる場合があります)。簡単な例を見てください:

1   0   0   0   0   0

0   1   1   1   0   0

私はどのように多くの一意の列(数字や一致する順序など)を確認したいと思います。この場合は3です。

これを行うための簡単な1行のコードはありますか?ある列を別の列と比較するのは簡単ですが、同じ列を見つける方法は何ですか?

答え1

次のパイプラインを使用して一意の列を計算できます。

$ awk '{for (i=1; i<=NF; ++i) a[i]=a[i]$i; } END { for (i in a) print a[i] }' foo \
  | sort -u | wc -l

awkコマンドは入力を転置し、一意の行のみを維持しながら結果行をソートし(-u)、最後にすべての(固有の)行(つまり、転置された列)の数を数えます(wc -l)。

これはNF組み込み awk 変数で、現在のレコードのフィールド数に自動的に設定されます。$ii番目のフィールドを参照して、ENDすべてのレコード処理が完了した後に実行されるように、次のブロックを保護します。 awk は、デフォルトでは空白と空白ではなく、フィールド区切りを使用します。

答え2

(((...))) しかし、同じ列を見つける方法は?

$ printf '%s\n' '1 0 0 0 0 0' '0 1 1 1 0 0' | awk -vSUBSEP='=' '
    { for (i=1; i<NF; i++)
        for (j=i+1; j<=NF; j++)
          if ($i==$j)
            M[i,j]++
    }
    END{ for (m in M) if (M[m]==NR) print m }'
5=6
2=3
2=4
3=4

i<j各行のすべての列について、その列のM[i,j]値が等しい場合は常に増加します。したがって、行をM[i,j]==NR読み取った後は、読み取っNRたすべての行に対して値が同じになります。

答え3

この質問は私に多くの関心を持っていますが、私が正確に知らない部分に近づいて良い助けを得たいと思います。別の質問で投稿した後。私が投稿した質問を見ると、私が従う方法を理解できます。

この問題には2つの解決策があります(その1つグヌークス正解は真珠ソリューションとは異なるソリューション ジョーンズ私のソリューションと組み合わせたソリューション)。

#The variable appended_input will remove spaces/tabs and just append the rows. 
#Modify the file name in this line. Here I use inputfile as the filename. 

appended_input=$(column -s '\t' inputfile | tr -d '[:space:]') ;

#The array variable will store each column-wise value as an array element.  
#I use sort to find the number of unique elements.

array=($(
    for ((i=0; i<6; i++))
    do
        new=${appended_input:$i:1}
        for ((j=i+6; j<${#appended_input}; j=j+6))
        do 
            new="$new${appended_input:$j:1}"
        done
        echo "$new"
    done
    )) | echo "${array[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' '

テスト

私の入力ファイルは次のとおりです。

1 0 0 1 0 0
0 1 1 0 0 0
1 1 1 1 1 0
1 0 0 1 0 1
1 0 0 1 0 1

上記のスクリプトを実行した後に得た結果は次のとおりです。

00011 00100 01100 10111

aを最後にパイプすると、wc -w上記のように一意の列値の代わりに4のみが出力されます。

答え4

以下は、gawkコプロセスを使用して各列を別々のインスタンスに供給し、一意のハッシュの合計数をsha256sum報告するソリューションです(ハッシュの競合の可能性がsha256sum統計的に有意ではないことを考慮すると、固有のハッシュの数は同じ固有の列と一致する必要があります)。 。数量)。一部の人々はこれを深刻なハッキングだと思うかもしれませんが、他の方法と比較してこのアプローチの1つの利点は、データを接続/転置しようとしないため、比較的メモリ効率が高いことです。

awk 'BEGIN{for(i=1; i<=6; ++i){s=sprintf("%*s", i+1, ""); a[i]="sha256sum"s}}
    {for (i=1; i<=6; ++i) print $i |& a[i]}
    END{com= "sort | uniq | wc -l"
    for (i=1; i<=6; ++i){close(a[i], "to"); a[i] |& getline x;
    close(a[i]); print x | com};
    close(com)}' file 

関連情報