다음과 같이 탭으로 구분된 파일이 있습니다.
cg13201342 F ARNT;ARNT;ARNT;CTSK 3'UTR;3'UTR;3'UTR;TSS1500
cg05269359 F SCN4B;SCN4B;SCN4B;SCN4B 3'UTR;3'UTR;3'UTR;Body
cg06018296 R NEK3;NEK3;NEK3;NEK3 3'UTR;3'UTR;3'UTR;Body
cg05172994 F WDR20;WDR20;WDR20;WDR20 3'UTR;3'UTR;3'UTR;Body
원하는 출력:
cg13201342 F ARNT 3'UTR
cg13201342 F ARNT 3'UTR
cg13201342 F ARNT 3'UTR
cg13201342 F CTSK TSS1500
cg05269359 F SCN4B 3'UTR
.
.
등.
나는 노력했다
awk 'BEGIN {
FS = OFS = "\t"
}
{
n = split($3, f, " *;*")
for (i=1; i<=n; i++)
print $1, f[i]
}' probe-genes-regions >chk
그러나 이는 세 번째 열만 분할합니다. 마지막 열을 두 번째 열과 분리하고 세 번째 열의 첫 번째 필드와 마지막 열의 첫 번째 필드 등으로 별도의 행을 형성하고 싶습니다.
답변1
예를 들어 필드 3과 4를 세미콜론을 사용하여 별도의 배열로 분할하고 반복합니다(필드 3과 4의 요소 수가 동일하다고 가정).
파싱.awk
BEGIN { OFS = "\t" }
{
n = split($3, a, /;/); split($4, b, /;/)
for(i=1; i<=n; i++)
print $1, $2, a[i], b[i]
}
다음과 같이 실행하세요:
awk -f parse.awk infile
산출:
cg13201342 F ARNT 3'UTR
cg13201342 F ARNT 3'UTR
cg13201342 F ARNT 3'UTR
cg13201342 F CTSK TSS1500
cg05269359 F SCN4B 3'UTR
cg05269359 F SCN4B 3'UTR
cg05269359 F SCN4B 3'UTR
cg05269359 F SCN4B Body
cg06018296 R NEK3 3'UTR
cg06018296 R NEK3 3'UTR
cg06018296 R NEK3 3'UTR
cg06018296 R NEK3 Body
cg05172994 F WDR20 3'UTR
cg05172994 F WDR20 3'UTR
cg05172994 F WDR20 3'UTR
cg05172994 F WDR20 Body
답변2
사용밀러( mlr
):
sed 's/;/\t/' file | mlr --nidx --fs tab nest --evar ';' -f 4
먼저 각 줄의 첫 번째 줄을 탭으로 sed
바꾸고 ;
탭으로 구분된 세 번째 필드를 두 개의 개별 필드로 분할합니다. GNU는 sed
이 명령을 사용하여 탭 문자를 삽입할 수 있지만 모든 구현이 가능한 것은 아닙니다. 그렇게 할 수 없으면 + 를 누르는 대신 리터럴 탭 문자를 입력하세요.\t
s
sed
\t
Ctrl+VTab
그런 다음 Miller는 탭으로 구분된 데이터( )를 읽고 쓰고 네 번째 탭으로 구분된 필드( )의 구분된 하위 필드를 기반으로 --nidx --fs tab
각 레코드를 "폭발"(또는 "중첩 해제")합니다 .;
nest --evar ';' -f 4
질문의 데이터 출력을 제공합니다.
cg13201342 F ARNT ARNT
cg13201342 F ARNT ARNT
cg13201342 F ARNT CTSK 3'UTR
cg13201342 F ARNT 3'UTR
cg13201342 F ARNT 3'UTR
cg13201342 F ARNT TSS1500
cg05269359 F SCN4B SCN4B
cg05269359 F SCN4B SCN4B
cg05269359 F SCN4B SCN4B 3'UTR
cg05269359 F SCN4B 3'UTR
cg05269359 F SCN4B 3'UTR
cg05269359 F SCN4B Body
cg06018296 R NEK3 NEK3
cg06018296 R NEK3 NEK3
cg06018296 R NEK3 NEK3 3'UTR
cg06018296 R NEK3 3'UTR
cg06018296 R NEK3 3'UTR
cg06018296 R NEK3 Body
cg05172994 F WDR20 WDR20
cg05172994 F WDR20 WDR20
cg05172994 F WDR20 WDR20 3'UTR
cg05172994 F WDR20 3'UTR
cg05172994 F WDR20 3'UTR
cg05172994 F WDR20 Body
이 작업은 uniq
인접한 행에서 중복 항목을 제거합니다.
다음만 사용하세요 awk
:
awk -F '\t' 'BEGIN { OFS=FS }
{
nf = split($3,a,";")
for (i = 2; i <= nf; ++i) print $1, $2, a[1], a[i]
}' file
이렇게 하면 세 번째 필드가 분할 ;
되고 세 번째 필드의 두 번째 하위 필드에 대해 처음 두 필드와 원래 세 번째 필드의 첫 번째 하위 필드가 계속 출력됩니다.
그 출력은 이 답변의 상단에 있는 파이프의 출력과 동일합니다.
답변3
입력의 공백에 관계없이 POSIX awk를 사용하십시오.
$ awk -F'[[:space:];]+' -v OFS='\t' '{
n=(NF-2)/2; for (i=1; i<=n; i++) print $1, $2, $(2+i), $(2+i+n)
}' file
cg13201342 F ARNT 3'UTR
cg13201342 F ARNT 3'UTR
cg13201342 F ARNT 3'UTR
cg13201342 F CTSK TSS1500
cg05269359 F SCN4B 3'UTR
cg05269359 F SCN4B 3'UTR
cg05269359 F SCN4B 3'UTR
cg05269359 F SCN4B Body
cg06018296 R NEK3 3'UTR
cg06018296 R NEK3 3'UTR
cg06018296 R NEK3 3'UTR
cg06018296 R NEK3 Body
cg05172994 F WDR20 3'UTR
cg05172994 F WDR20 3'UTR
cg05172994 F WDR20 3'UTR
cg05172994 F WDR20 Body