텍스트를 값으로 바꾸기

텍스트를 값으로 바꾸기

하나로 병합해야 할 두 개의 파일이 있습니다.

파일 1 예:

gene_1  578
gene_2  565
gene_3  3
gene_4  77
gene_5  8
gene_6  0
gene_7  45
gene_8  67
gene_9  0
gene_10 65

파일 2 예:

COG0430 gene_5 gene_9       
COG1949 gene_1 gene_3 gene_6
COG5049 gene_2 gene_4 gene_7 gene_10
COG5104 gene_8

출력 파일은 다음과 같아야 합니다.

COG0430 8 0 
COG1949 578 3 0
COG5049 565 77 45 65
COG5104 67

이 문제를 해결할 수 있는 명령어를 아는 사람이 있나요?

답변1

#!/bin/bash
declare -A arr
readarray -t lines < "file1"

for line in "${lines[@]}"; do
   arr[${line%% *}]=${line#* }
done

readarray -t lines2 < "file2"

for line in "${lines2[@]}"; do
    echo -n "${line%% *} "
    for word in $line; do
        echo -n "${arr[$word]} "
    done
    echo
done

가장 깨끗한 bash는 아니지만 작동합니다. 또한 bash >= 4.2인지 확인하세요.

답변2

이것은 한 가지 방법입니다

awk '/^gene/{a[$1]=$2}/^COG/{c=$1;for(b=1;b<=NF;b++){c=sprintf("%s%s%c",c,a[$b],b==NF?"":" ")}print c}' file1 file2
COG0430 8 0
COG1949 578 3 0
COG5049 565 77 45 65
COG5104 67
  • /gene/{a[$1]=$2}"gene"으로 시작하는 행을 찾아 첫 번째 열의 키(예: "gene_1")와 다음 열의 값(예: "578")을 포함하는 항목 배열을 만듭니다.
  • /^COG/"COG"로 시작하는 줄을 찾으세요...
  • c=$1변수 c를 "COG0430"과 같은 첫 번째 열로 설정합니다.
  • {c=sprintf("%s%s%c",c,a[$b],b==NF?"":" "각 열의 배열 항목을 변수 c에 계속 추가합니다. 마지막 열이 아닌 경우 공백 구분 기호를 추가하세요.
  • print c그런 다음 변수 "c"의 전체 형식을 인쇄하십시오.

답변3

이것을 시도해 볼 수 있습니다.

awk '
  NR == FNR {
    a[$1] = $2
    next
  }
  {
    for ( i = 2 ; i <= NF ; i++)
    $i = a[$i]
  }
1' file1 file2

아니면 줄을 서서

awk 'NR==FNR{a[$1]=$2;next}{for(i=2;i<=NF;i++)$i=a[$i]}1' file1 file2

답변4

 perl -ale '
    $h{$F[0]}=$F[1],next if @ARGV;
    my $k;
    print s/\H+/$k++ ? $h{$&} : $&/reg;
 ' file1 file2

° 첫 번째 파일을 읽고 @ARGV두 번째 매개변수를 저장하므로 true를 반환합니다.

%h°file1의 각 행에 대해 유전자 이름인 키와 두 번째 필드의 해당 값으로 해시를 채웁니다.

° 두 번째 파일의 경우 @ARGV에는 아무것도 포함되지 않으므로 false가 반환됩니다. 마지막 두 줄의 코드는 file2의 각 줄에 대해 실행됩니다.

° file2의 한 줄을 읽을 때마다 count 변수를 초기화합니다. 그런 다음 \H+수평이 아닌 공백 문자, iow, 필드와 일치해야 합니다. 두 번째부터 시작하여 유전자 이름 => 유전자 번호에 대한 서브루틴이 트리거됩니다.

Gnu 확장 기능을 갖춘 sed 편집기로도 다음 작업을 수행할 수 있습니다.

 sed -Ee '
     # store file1 in hold
    /^C/!{H;1h;d;}

    # place a traveling marker \n\n at $2
    s/$/ /
    G
    s/(\S+\s+)/&\n\n/

    # effect gene name => gene number 
    :a
       s/\n\n(\S+)[ ]+((.*\n)?\1\s+([0-9]+))/ \4\n\n\2/
    ta

   # take away marker and hold portion
    s/\n\n.*//
 ' file1 file2 

관련 정보