동일한 열의 테이블로 변환하기 위해 가변 개수의 구분 기호가 있는 테이블을 구문 분석하려고 합니다.
cluster=96\troot\tcellular organisms\tno_rank no_rank$
cluster=42\troot\tcellular organisms\tBacteria\tno_rank\tno_rank\tsuperkingdom$
cluster=362\troot\tcellular organisms\tBacteria\tProteobacteria\tno rank\tno rank\tsuperkingdom\tphylum$
cluster=12330\troot\tcellular organisms\tBacteria\tTerrabacteria\tFirmicutes\tClostridia\tClostridiales\tClostridiaceae\tClostridium\tno rank\tno rank\tsuperkingdom\tno rank\tphylum\tclass\torder\tfamily\tgenus$
예상되는 출력은 다음과 같습니다.
cluster=96\troot\tcellular organisms\t\t\t\t\t\t\t\tno_rank\tno_rank\t\t\t\t\t\t\t$
cluster=42\troot\tcellular organisms\tBacteria\t\t\t\t\t\t\tno_rank\tno_rank\tsuperkingdom\t\t\t\t\t\t$
cluster=362\troot\tcellular organisms\tBacteria\tProteobacteria\t\t\t\t\t\tno rank\tno rank\tsuperkingdom\tphylum\t\t\t\t\t$
cluster=12330\troot\tcellular organisms\tBacteria\tTerrabacteria\tFirmicutes\tClostridia\tClostridiales\tClostridiaceae\tClostridium\tno rank\tno rank\tsuperkingdom\tno rank\tphylum\tclass\torder\tfamily\tgenus$
"\t"는 탭 구분 기호이고 "$"는 줄 끝입니다.
답변1
Awk를 사용하여 두 가지 패스를 만듭니다.
awk -F'\t' -v OFS='\t' 'FNR==NR {if (NF>a) {a=NF}; next} NF<a{$a=""} 1' file file
그러면 다음 위치에 추가 탭이 추가됩니다.끝누락된 필드가 있는 행.
귀하의 정확한 예제 데이터를 토대로 볼 때 귀하는 프로그래밍 방식으로 해결할 수 없는 문제를 다루고 있는 것 같습니다. 값이 올바른 열에 있는지 확인하기 위해 중간에 추가 탭을 추가해야 하는 경우 no_rank
더 멋진 논리가 필요합니다.
답변2
사용밀러: 비슷한 질문에 답변한 적이 있습니다.여기에 CSV하지만 이 경우 헤더 행에 최대 길이가 이미 제공되어 있으므로 다른 곳에서 검색할 필요가 없습니다.
이 경우 최대 길이는 다른 곳에 있을 수 있으며 내가 할 수 있는 최선은 다음과 같습니다.
cat in.dat | mlr --nidx --fs tab --nidx put -q '
@maxnf = max(@maxnf, NF);
@records[NR] = $*; # Retain
@counts[NR] = NF;
end {
for (i in @records) {
@record = @records[i];
for (j = @counts[i] + 1; j <= @maxnf; j += 1) { # add extra fields
@record["x".j] = "";
}
emit @record; # insert into the output record stream
}
}
'
아이디어는 레코드 목록과 최대 NF를 유지한 다음 이를 끝 블록에서 처리하는 것입니다. 이는 head의 기능을 사용한다는 점에 유의하십시오(최신 4.5.0 버전이 아님).