열 일치 및 바꾸기

열 일치 및 바꾸기

공백으로 구분된 필드가 있는 두 개의 매우 큰 텍스트 파일이 있습니다.

파일 1

527858  51  2   27.92464882 8.63E-07
570289  82  2   30.12532071 2.87E-07
571034  90  2   29.26089611 4.43E-07
571033  90  2   28.56723908 6.26E-07
452403  104 2   28.27577506 7.24E-07
351390  100 2   28.16226794 7.67E-07
527858  50  2   27.92464882 8.63E-07

파일 2

527858  rs435           
570289  rs564           
571034  rs654           
571033  rs345           
452403  rs665           
351390  rs787           
527858  rs435           

산출:

rs435   51  2   27.92464882 8.63E-07
rs564   82  2   30.12532071 2.87E-07
rs654   90  2   29.26089611 4.43E-07
rs345   90  2   28.56723908 6.26E-07
rs665   104 2   28.27577506 7.24E-07
rs787   100 2   28.16226794 7.67E-07
rs435   50  2   27.92464882 8.63E-07

file1과 file2의 첫 번째 열을 비교하고 file1의 첫 번째 열을 file2의 두 번째 열에 있는 이름 으로 바꿉니다.

답변1

나는 노력할 것이다

awk 'FNR==NR { F2[$1]=$2 ; next } $1 in F2 {$1 = F2[$1] ; print } ' File2 File1

어디

  • FNR==NR { F2[$1]=$2 ; next }File1에 값을 저장합니다.
  • $1 = F2[$1]키 교체

답변2

이는 awk에서와 동일한 기본 아이디어 입니다.아케마의 대답, Perl로 구현됨:

$ perl -lane '$#F>1?print"$l{$F[0]} @F[1..$#F]":($l{$F[0]}=$F[1])' file2 file1
rs435 51 2 27.92464882 8.63E-07
rs564 82 2 30.12532071 2.87E-07
rs654 90 2 29.26089611 4.43E-07
rs345 90 2 28.56723908 6.26E-07
rs665 104 2 28.27577506 7.24E-07
rs787 100 2 28.16226794 7.67E-07
rs435 50 2 27.92464882 8.63E-07

설명하다

  • -lane: -l각 호출에 개행 문자를 추가 print하고 각 입력 줄에서 후행 개행 문자를 제거합니다. -amake가 수행하는 perl작업은 다음과 같습니다 awk. 각 입력 행을 자동으로 배열로 분할합니다 @F. 따라서 첫 번째 필드는 $F[0], 두 번째 필드 $F[1]등이 됩니다 . -nPerl에게 입력 파일을 한 줄씩 읽고 주어진 스크립트를 -e각 파일에 적용하도록 지시합니다.

  • $#F>1? ... : ...: C 스타일 조건부 연산자입니다. 일반적인 형식은 다음과 같습니다 condition ? foo : bar. " conditiontrue이면 do foo, true가 아니면 do bar. 이것은 $#F배열의 배열 인덱스 수입니다 @F. 배열은 로 시작하므로 0값은 1두 요소를 포함하는 배열을 나타냅니다. 따라서 print ...이것은 배열에 2개 이상의 요소가 있는 경우에만 작동하며 첫 번째 블록(아래 참조)이 실행됩니다 file1.

  • ($l{$F[0]}=$F[1]): 이것은 file2의 각 라인, 3개 미만의 필드가 있는 각 라인에 대해 실행됩니다. %l키가 첫 번째 숫자 필드 file2이고 값이 관련 rsID인 해시를 채웁니다 .
  • print"$l{$F[0]} @F[1..$#F]"%l: 첫 번째 필드( )의 해시에 있는 rsID를 $l{$F[0]}공백으로 인쇄한 다음 줄( $F[1..$#F])의 나머지 필드를 인쇄합니다.

개인적으로 저는 아마도 해당 awk솔루션을 사용하거나 최악의 경우 perl제가 제공한 솔루션을 사용할 것입니다. 왜냐하면 파일을 정렬할 필요가 없기 때문입니다. 그러나 태그를 지정했으므로 join도구를 사용하는 방법은 다음과 같습니다.

$ join -o 2.2 1.2 1.3 1.4 1.5 <(sort file1) <(sort file2)
rs787 100 2 28.16226794 7.67E-07
rs665 104 2 28.27577506 7.24E-07
rs435 50 2 27.92464882 8.63E-07
rs435 50 2 27.92464882 8.63E-07
rs435 51 2 27.92464882 8.63E-07
rs435 51 2 27.92464882 8.63E-07
rs564 82 2 30.12532071 2.87E-07
rs345 90 2 28.56723908 6.26E-07
rs654 90 2 29.26089611 4.43E-07

관련 정보