タイトルの後のすべての項目が特定の文字列の場合、列を削除する

タイトルの後のすべての項目が特定の文字列の場合、列を削除する

以下のデータファイルがあります。

Sample1 Sample2 Sample3 Sample4 Sample5 Sample6
./.       ./.      ./.    ./.     ./.    ./.
./.       ./.      ./.    ./.     A/G    ./.
./.       ./.      ./.    ./.     ./.    ./.
A/A       A/A      A/G    ./.     ./.    ./.

./のみを含むすべての列を削除したいです。私に任せて

Sample1 Sample2 Sample3 Sample5
  ./.     ./.     ./.     ./.
  ./.     ./.     ./.     A/G
  ./.     ./.     ./.     ./.
  A/A     A/A     A/G     ./.

私はこれがsedまたはawkコマンドだと思いますが、助けてくれてありがとう。

答え1

使用awk:

awk -v na="./." '
BEGIN{OFS=FS}
NR==FNR && NR>1 {
  for(i=1;i<=NF;i++){if($i!=na){s[i]=1}}
}
NR!=FNR {
  for(l in s){true} 
  for(i in s){if (i!=l){printf "%s"OFS,$i} else {printf "%s\n",$i}}
}
' file file

ファイルがタブで区切られている場合は、にBEGIN{OFS=FS}変更する必要があります。BEGIN{OFS=FS="\t"}

説明する:

  • ファイルを2回参照( awk ... file file)
  • NR==FNRヘッダーを除外するために最初に列()の1つ以上の値ではないことNR>1を確認した場合は、列番号を変数に保存します。ina="./."s
  • 2番目の時間( )、NR!=FNR印刷された列の値に含まれる各列について。 (最初のループを使用すると、印刷する最後の列を知ることができます(印刷または.の間で決定できるように変数に保存されsます)。lOFS\n

出力:

Sample1 Sample2 Sample3 Sample5
./. ./. ./. ./.
./. ./. ./. A/G
./. ./. ./. ./.
A/A A/A A/G ./.

ファイルがタブで区切られている場合、出力は少し良くなります|column -t。それ以外の場合は、次のように追加できます。

Sample1  Sample2  Sample3  Sample5
./.      ./.      ./.      ./.
./.      ./.      ./.      A/G
./.      ./.      ./.      ./.
A/A      A/A      A/G      ./.

答え2

$ perl -F'\t' -lane '
   push @{$AoA[$.-1]}, map { push @Cols2Keep, $_ if $. > 1 && $F[$_] ne "./." && !$seen{$_}++; $F[$_] } 0 .. $#F}
   {print join "\t", @{$AoA[$_]}[sort { $a <=> $b } @Cols2Keep] for 0 .. $#AoA
' file.tsv

結果:

Sample1 Sample2 Sample3 Sample5
./.     ./.     ./.     ./.
./.     ./.     ./.     A/G
./.     ./.     ./.     ./.
A/A     A/A     A/G     ./.

布材:

  • @AoA配列の配列は、レコード番号でインデックス付けされた配列にファイルを保存します$.$.1から始まり、配列は私たちによって正規化さPerlれるからです。0-indexed$.
  • non ./.@Cols2keep配列は、要素が見つかった列番号を格納します。また、重複したくないので、ハッシュを介して重複を削除し、ハッシュのキーは%seenこれらの列番号です。制限は、最初のレコードの確認をスキップすることです。

関連情報