하나로 병합해야 할 두 개의 파일이 있습니다.
파일 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