제목 뒤의 모든 항목이 특정 문자열인 경우 열 제거

제목 뒤의 모든 항목이 특정 문자열인 경우 열 제거

아래와 같은 데이터 파일이 있습니다.

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"}

설명하다:

  • 파일을 두 번 찾아보기( awk ... file file)
  • NR==FNR헤더를 제외하기 위해 처음으로 열( )에 있는 하나 이상의 값이 이 아닌 NR>1것을 확인하는 경우 열 번호를 변수에 저장합니다 .ina="./."s
  • 두 번째 시간( ), 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해시의 키는 이러한 열 번호입니다. 제한 사항은 첫 번째 레코드 확인을 건너뛴다는 것입니다.

관련 정보