쉼표를 제거하고 쉼표 뒤의 전체 단어 줄을 다시 인쇄하는 방법

쉼표를 제거하고 쉼표 뒤의 전체 단어 줄을 다시 인쇄하는 방법

문서:

chr1_156186369  chr1_156186369_A_C,T    A   C,T  33150.29  1/2:0,4,6:10:88:272
chr19_27732257  chr19_27732257_G_C      G   C    262.29    1/2:1,10,7:18:99:414,167
chrM_2619       chrM_2619_A_G,T         A   G,T  33023.29  1/2:0,5,5:10:99:293,144,129
chr9_119375271  chr9_119375271_T_A,G    T   A,G  248.29    1/2:1,11,5:17:99:359,107,113

2열과 4열에서 쉼표를 제거하고 쉼표 뒤의 단어 전체 줄을 인쇄하면 됩니다.

예상되는 출력은 다음과 같습니다.

chr1_156186369  chr1_156186369_A_C  A   C   33150.29  1/2:0,4,6:10:88:272
chr1_156186369  chr1_156186369_A_T  A   T   33150.29  1/2:0,4,6:10:88:272 
chr19_27732257  chr19_27732257_G_C  G   C   262.29    1/2:1,10,7:18:99:414,167
chrM_2619       chrM_2619_A_G       A   G   33023.29  1/2:0,5,5:10:99:293,144,129
chrM_2619       chrM_2619_A_T       A   T   33023.29  1/2:0,5,5:10:99:293,144,129
chr9_119375271  chr9_119375271_T_A  T   A   248.29    1/2:1,11,5:17:99:359,107,113
chr9_119375271  chr9_119375271_T_G  T   G   248.29    1/2:1,11,5:17:99:359,107,113 

awk를 시도했지만 결과를 얻지 못했습니다. 여기에서도 비슷한 유형의 질문을 읽었습니다. 특정 조건에서 파일에서 줄을 추출하는 방법

답변1

awk를 사용하세요:

awk '{
  split ($2,w2,",");
  split ($4,w4,",");
  for (i in w4) {
    print $1,substr(w2[1],0,length(w2[1])-length(w4[i])) w4[i],$3,w4[i],$5,$6;
  }}'

2열과 4열의 쉼표 뒤의 값이 동일하지 않으면 오류 처리가 발생하지 않습니다.

답변2

sed단일 문자로 구분된 값이 C,T반복된다고 가정

$ sed -E 's/^(.*)([A-Z]),([A-Z])(.*)\2,\3(.*)/\1\2\4\2\5\n\1\3\4\3\5/' ip.txt 
chr1_156186369  chr1_156186369_A_C    A   C  33150.29  1/2:0,4,6:10:88:272
chr1_156186369  chr1_156186369_A_T    A   T  33150.29  1/2:0,4,6:10:88:272
chr19_27732257  chr19_27732257_G_C      G   C    262.29    1/2:1,10,7:18:99:414,167
chrM_2619       chrM_2619_A_G         A   G  33023.29  1/2:0,5,5:10:99:293,144,129
chrM_2619       chrM_2619_A_T         A   T  33023.29  1/2:0,5,5:10:99:293,144,129
chr9_119375271  chr9_119375271_T_A    T   A  248.29    1/2:1,11,5:17:99:359,107,113
chr9_119375271  chr9_119375271_T_G    T   G  248.29    1/2:1,11,5:17:99:359,107,113
  • ^(.*)텍스트 시작
  • ([A-Z]),([A-Z])쉼표로 구분된 단일 문자
  • (.*)반복 사이의 텍스트
  • \2,\3다시 쉼표로 구분된 단일 문자와 일치합니다.
  • (.*)남은 줄
  • \1\2\4\2\5\n\1\3\4\3\5원하는 출력 형식
  • 간격이 예상 출력과 정확히 일치하지 않습니다.

답변3

단일 명령으로 이 작업을 수행하는 방법을 모르지만 다음 루프에서 작동합니다 bash.

cat data.dat | while read line
do
  if echo "${line}" | grep -q '[[:alpha:]],[[:alpha:]]'
  then
    letters=`echo "${line}" | grep -o '[[:alpha:]],[[:alpha:]]' | head -n 1`
    for letter in `echo ${letters} | sed 's/,/ /g'`
    do
      echo "${line}" | sed 's/'"${letters}"'/'"${letter}"'  /g'
    done
  else
    echo "${line}"
  fi
done

답변4

네 번째 필드를 쉼표로 분할하고 해당 열의 조각을 사용하고 _X,Y마지막 필드를 로 바꿉니다( _slice있는 경우).

awk '{
      n=split($4,slices,",")
      for(i=1;i<=n;i++) {
        res=$2
        sub(/.,.*/,slices[i],res)
        print $1, res, $3, slices[i], $5, $6
      }
     }' file

필드 1부터 6까지 표시하기 때문에 필드가 인쇄되는 방식이 마음에 들지 않으므로 이것이 정적이기를 바랍니다.

$ awk '{n=split($4,slices,","); for(i=1;i<=n;i++) {res=$2; sub(/.,.*/,slices[i],res); print $1, res, $3, slices[i], $5, $6}}' a
chr1_156186369 chr1_156186369_A_C A C 33150.29 1/2:0,4,6:10:88:272
chr1_156186369 chr1_156186369_A_T A T 33150.29 1/2:0,4,6:10:88:272
chr19_27732257 chr19_27732257_G_C G C 262.29 1/2:1,10,7:18:99:414,167
chrM_2619 chrM_2619_A_G A G 33023.29 1/2:0,5,5:10:99:293,144,129
chrM_2619 chrM_2619_A_T A T 33023.29 1/2:0,5,5:10:99:293,144,129
chr9_119375271 chr9_119375271_T_A T A 248.29 1/2:1,11,5:17:99:359,107,113
chr9_119375271 chr9_119375271_T_G T G 248.29 1/2:1,11,5:17:99:359,107,113

관련 정보