데이터 파일이 있습니다 A.tsv
(필드 구분 기호 = \t
).
id clade mutation
243 40A SDF
254 20B
261 40A
267 20B
B.tsv
(필드 구분 기호 = \t
):
id clade mutation
243 40A
254 20B
261 40A
267 20B SLT
C.tsv
(필드 구분 기호 = \t
):
id clade mutation
243 40A
254 20B
261 40A MGG
267 20B
모든 파일 간에 다른 유일한 열은 열이라는 것을 알고 모든 파일을 하나로 연결하고 싶습니다 mutation
. 예상되는 결과는 다음과 같습니다.
id clade mutation
243 40A SDF
254 20B
261 40A MGG
267 20B SLT
지금까지 나는 다음을 시도했습니다.
awk 'BEGIN{FS=OFS="\t"} NR==FNR{klos[NR]=$3; next} $3==""{$3=klos[FNR]} 1' *.tsv > output.tsv
하지만 작동하지 않습니다. 할 수 있는 방법이 있나요? 감사해요
추신: 이것은 샘플 테스트입니다. 실제 경우에는 3개 이상의 파일이 있습니다. 하지만 예제와 마찬가지로 mutation
해당 열에 동일한 내용을 가진 두 개의 파일이 없습니다.
답변1
모든 Unix 시스템의 모든 쉘에서 awk를 사용하십시오.
$ cat tst.awk
BEGIN { FS=OFS="\t" }
(NR == FNR) || ($3 != "") {
fnr2rec[FNR] = $0
}
FILENAME == ARGV[ARGC-1] {
print fnr2rec[FNR]
}
$ awk -f tst.awk A.tsv B.tsv C.tsv
id clade mutation
243 40A SDF
254 20B
261 40A MGG
267 20B SLT
답변2
그런 다음 다음을 사용하여 paste
출력을 처리합니다 awk
.
paste file[ABC].tsv |\
awk 'BEGIN{ FS=OFS="\t" } { for(i=3; i<=NF; i+=3) if($i"")break; print $1, $2, $i }'
사용되는 조건은 if($i"")break
null이 아닌 첫 번째 필드가 발견되면 for 루프를 중단한 다음(awk가 문자열 비교를 수행하도록 하려면 큰따옴표를 사용함) 필드 #1, #2 및 이전에 발견된 null이 아닌 필드만 인쇄하는 것입니다. 필드 #i Pass에 있습니다.
답변3
이것은 효과가 있을 것입니다(반대의 결과가 마음에 들지 않는다면).
[root@SE ~]# awk 'BEGIN{FS=OFS="\t"} { if($3>0) { print }}' A.tsv B.tsv C.tsv | sort -ru
나는 에 익숙하지 않기 때문에 아마도 이것을 달성하는 더 쉬운 방법이 있을 것이라고 확신합니다 awk
.
내가 한 일은 3개의 파일을 모두 인쇄하고 변형에서 문자가 없는 모든 줄을 제거하는 것뿐이었습니다. 그런 다음 파이프라인은 sort -u
모든 중복 항목을 제거합니다. 이 -r
플래그는 순서를 반대로 합니다.
[root@SE ~]# awk 'BEGIN{FS=OFS="\t"} { if($3>0) { print }}' A.tsv B.tsv C.tsv | sort -ru
id clade mutation
267 20B SLT
261 40A MGG
254 20B SLT
243 40A SDF
@Quasimodo는 이것을 단순화했습니다. 감사해요.
awk 'BEGIN{FS=OFS="\t"} (FNR>1 || NR==1) && $3' A.tsv B.tsv C.tsv
처리된 첫 번째 줄(즉, 첫 번째 입력 파일의 헤더)이거나 처리된 모든 줄인 경우 한 줄을 인쇄합니다.아니요헤더이지만 비어 있지 않은 세 번째 필드가 포함되어 있습니다. { ... }
규칙 블록( ) 외부의 부울 표현식이 "true"로 평가되어 awk
현재 행이 인쇄되어야 함 을 나타내기 때문에 작동합니다 .
답변4
Bash 명령줄 유틸리티를 사용하는 한 가지 방법은 다음과 같습니다.
## initialization
ref= tmpdir=$(mktemp -d) cn=3
for f in ./*.tsv;do
: ${ref:="$f"}
< "$f" cut -f"$cn" > "$tmpdir/$f"
done
paste <(cut -f-"$((cn-1))" "$ref") "$tmpdir"/* |
tr -s '\t' |
sed -ne "1s/\t/\n/$cn" -e 's/\t*$//;P'
결과:
id clade mutation
243 40A SDF
254 20B
261 40A MGG
267 20B SLT