제목(첫 번째 행)에 "_HET" 문자열이 포함된 텍스트 파일에서 탭으로 구분된 모든 열을 제거하고 싶습니다. 입력 텍스트 파일은 다음과 같습니다.
rs36810213_HET rs2438689 rs70927523570_HET rs54666437 ...
1 0 2 0
0 1 0 1
2 0 1 1
... ... ... ...
출력 텍스트 파일은 다음과 같아야 합니다.
rs2438689 rs54666437 ...
0 0
1 1
0 1
... ...
내가 사용하는 코드는 아무것도 삭제하지 않습니다.
#!/bin/bash
path="/data/folder"
awk -v OFS='\t' '
NR==1{
for (i=1;i<=NF;i++)
if ($i=="_HET") {
n=i-1
m=NF-(i==NF)
}
}
{
for(i=1;i<=NF;i+=1+(i==n))
printf "%s%s",$i,i==m?ORS:OFS
}
' $path/input.txt >> $path/output.txt
이 코드를 수정하는 방법에 대한 제안 사항이 있습니까? 감사합니다!
답변1
awk -F '\t' -f script.awk file
script.awk
어디
BEGIN { OFS = FS }
FNR == 1 {
for (i = 1; i <= NF; ++i)
if ($i !~ /_HET/)
keep[i] = 1
}
{
nf = split($0, fields, FS)
$0 = ""
j = 0
for (i = 1; i <= nf; ++i)
if (i in keep)
$(++j) = fields[i]
print
}
keep
먼저 첫 번째 줄의 헤더를 구문 분석하고 연관 배열 에 유지하려는 헤더를 기억하세요 .
그런 다음 각 행에 대해 유지하려는 필드에서만 현재 레코드(행)를 다시 만들고 인쇄합니다.
현재 필드 구분 기호의 행을 배열로 (재)분할한 fields
다음 비워서 이를 수행합니다.모두필드( 를 사용하면 $0 = ""
재설정됨 NF
)를 선택하고 마지막으로 배열 fields
의 키인 필드 만 할당합니다 keep
.
어떤 사람들은 재치 있는 말을 하는 것을 좋아합니다.
awk -F '\t' -v OFS='\t' 'FNR==1{for(i=1;i<=NF;++i)if($i!~/_HET/)k[i]=1}{n=split($0,f,FS);$0=j="";for(i=1;i<=n;++i)if(i in k)$(++j)=f[i]}1' file
귀하의 코드를 정확하게 따르지는 않았지만 :th 필드를 string 과 비교 $i=="_HET"
합니다 . 이 필드의 값이i
_HET
정확히 _HET
(귀하의 제목 필드가 없습니다.)
완전히 다른 접근 방식:
cut -f "$( awk -F '\t' -v OFS="," '{for(i=1;i<=NF;++i)if($i!~/_HET/)k[i]=1;$0="";for(i in k)$(++j)=i;print;exit}' file )" file
이 awk
신청서
BEGIN { OFS = "," }
{
for (i = 1; i <= NF; ++i)
if ($i !~ /_HET/)
keep[i] = 1
$0 = ""
for (i in keep)
$(++j) = i
print
exit
}
출력 없음콘텐츠원하는 열 수이지만 해당 열 번호를 쉼표로 구분된 문자열로 출력합니다. 그런 다음 이 문자열은 cut
데이터에서 열을 제거하는 데 사용됩니다 .
답변2
Perl을 사용하여 다음과 같이 이 작업을 수행할 수 있습니다.
$ perl -F'/\t/' -pale '$"="\t";
$. == 1 and @A = grep { $F[$_] !~ /_HET/ } 0 .. $#F;
$_ = "@F[@A]";
' input.tsv