
나와 관련된 데이터를 추출하는 csv 파일이 있습니다. 한편에는 참조 번호가 있고 다른 한편에는 문자 G, A, T 및 C 형태의 유전 정보가 있습니다.
콘텐츠 CSV:
1,S188823,188823,,,,ACTCTCGA,,CTGTACCA,ID23,
1,S189843,189843,,,,ACCCTGGA,,CTTGTACA,ID23,
...
나에게 관련된 정보는 188823,,,,ACCCTGGA,,CTTGTACA
모든 라인에서 나옵니다. 이 과정에서 중복 항목을 제거해야 합니다. 처음 두 줄도 잘려야 합니다.
이것이 내가 현재 하는 일이다:
cat File.csv | cut -d "," -f 3,9,7 | uniq | sed -e '1d' -e '2d'
결과는 다음과 같습니다.
188823,ACTCTCGA,CTGTACCA
189843,ACCCTGGA,CTTGTACA
...
하지만 이제 해야 할 일이 두 가지 있었는데, 나는 실패했습니다. 필드 3과 필드 2를 교환해야 합니다.
188823,CTGTACCA,ACTCTCGA
189843,CTTGTACA,ACCCTGGA
...
이제 field2부터 시작하여 염기는 "역상보적"이어야 합니다. 즉, 모든 A가 T가 되고, 모든 C가 G가 되고, 모든 G가 C가 되고, 모든 T가 A가 되고, 시퀀스 순서가 반대라는 의미입니다. 따라서 CTGTACCA
가 됩니다 TGGTACAG
.
최종 결과는 다음과 같아야 합니다.
188823,TGGTACAG,ACTCTCGA
188823,TGTACAAG,ACCCTGGA
이것이 이해할 수 있기를 바라며 당신이 나를 도울 수 있기를 바랍니다. 역보체 구성에 대한 도움말은 여기에서 찾을 수 있습니다. 온라인 RevComp 생성기
답변1
GNU 사용 awk
:
awk -F, '!seen[$3 FS $9 FS $7]++ {
cmd="echo \047" $9 "\047 | rev | tr ATCG TAGC";
if ((cmd |getline $9)>0){ print $3, $9, $7; };
close(cmd);
}' OFS=, infile
산출:
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA
NR>2
명령에 추가하면 awk 'NR>2{ ...; }'
입력의 처음 두 줄을 건너뛰는 것처럼 작동합니다.
여기서는 [getline
파이프에서 변수로 변환] cmd="..." $9 "..."
(외부 명령과 관련된 항목만 큰따옴표 안에 넣었습니다.) 그런 다음 Pipe에서 호출하여 getline
동일한 필드에 결과를 저장한 다음 $9
, getline
결과가 성공하면 출력에 필수 필드를 인쇄합니다.
마지막으로 우리는폐쇄(지침)이것주문하다우리는 열었습니다.
!seen[$3 FS $9 FS $7]++
처리 필드 #3, #9, #7에서 중복 행을 무시하는 데 사용됩니다.
답변2
$ cat tst.awk
BEGIN {
FS=OFS=","
map["A"] = "T"
map["C"] = "G"
map["G"] = "C"
map["T"] = "A"
}
{
str = ""
for (i=1; i<=length($9); i++) {
str = map[substr($9,i,1)] str
}
print $3, str, $7
}
$ awk -f tst.awk content.csv
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA
또는 awk에 함수를 tr
입력 하려는 경우 rev
:
$ cat tst.awk
BEGIN { FS=OFS="," }
{ print $3, rev(tr($9,"ACGT","TGCA")), $7 }
function tr(oldStr,oldChars,newChars, i,pos,oldChar,newStr) {
for (i=1; i<=length(oldStr); i++) {
oldChar = substr(oldStr,i,1)
pos = index(oldChars,oldChar)
newStr = newStr (pos ? substr(newChars,pos,1) : oldChar)
}
return newStr
}
function rev(oldStr, i,newStr) {
for (i=1; i<=length(oldStr); i++) {
newStr = substr(oldStr,i,1) newStr
}
return newStr
}
$ awk -f tst.awk content.csv
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA
아니면 두 가지를 모두 수행하는 함수:
$ cat tst.awk
BEGIN { FS=OFS="," }
{ print $3, trev($9,"ACGT","TGCA"), $7 }
function trev(oldStr,oldChars,newChars, i,pos,oldChar,newStr) {
for (i=1; i<=length(oldStr); i++) {
oldChar = substr(oldStr,i,1)
pos = index(oldChars,oldChar)
newStr = (pos ? substr(newChars,pos,1) : oldChar) newStr
}
return newStr
}
$ awk -f tst.awk content.csv
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA
답변3
우리는 이것을 사용할 수 있습니다 perl
.
- 행을 쉼표로 분할하고 필드를 0 인덱스 배열에 저장합니다
@F
. - 목록 구분 기호
$,
와 목록 결합자를$"
쉼표로 설정합니다. - 9번째 요소의 문자를 반전시킨
$F[8]
다음 문자 변환을 적용합니다.
$ perl -F, -lane '
BEGIN { $, = $" = ","; }
print $F[2], reverse($F[8]) =~ tr/ATGC/TACG/r, $F[6]
if $. > 2 && !$h{"@F[2,6,8]"}++;
' file
188823,TGGTACAG,ACTCTCGA
189843,TGTACAAG,ACCCTGGA