두 개의 파일이 있습니다.
Ref.txt에는 다음이 포함됩니다.
ABCDEFG,15147,ABC,ABCD,ABCDE
HIJKLMN,500,HIJKLM,HIJKL,HIJK
및 다음을 포함하는 Seq.txt
ABCDEFG
ABCXXXX
ABCDXXX
ABCDEXX
HIJKXXX
HIJKLXX
HIJKLMX
HIJKLMN
Ref.txt 파일의 각 줄의 3-end 필드에 대해 Seq.txt 파일을 검색하고 문자열이 있는 줄을 해당 줄의 첫 번째 필드에 있는 문자열로 바꾸고 싶습니다. 이 예에서 내가 찾고 있는 출력은 다음과 같습니다.
ABCDEFG
ABCDEFG
ABCDEFG
ABCDEFG
HIJKLMN
HIJKLMN
HIJKLMN
HIJKLMN
이것은 잘못된 코드이지만 다음과 같은 명령을 생각하고 있습니다.
awk '{for(i=3; i<=NF; i++) gsub( $i , $1)}
그러나 for 루프는 Ref.txt 파일을 참조하고 gsub 명령은 Seq.txt 파일에서 실행됩니다.
답변1
|
이를 수행하는 것을 고려할 수 있는 한 가지 방법은 Ref.txt의 각 줄의 세 번째 끝 필드에서 정규식을 연결하고 값으로 키가 지정된 연관 배열에 저장하여 단일 정규식을 작성하는 것입니다 $1
.
그런 다음 각 Seq.txt의 키를 반복할 수 있습니다 $1
.
awk -F, '
NR==FNR {
# construct a single ERE as $3|$4|$5|etc. keyed on $1
for(i=3;i<=NF;i++) r[$1] = r[$1] == "" ? $i : r[$1] "|" $i;
next
}
{
# test $1 against each ERE and substitute the first matching key
for(k in r) {
if ($1 ~ r[k]) {
$1 = k;
break
}
}
}
1
' Ref.txt Seq.txt
답변2
sed
다음과 같은 구성을 사용하여 Posix
이를 달성 할 수 있습니다 .
$ sed -ne '
/,/!G
y/\n_/_\n/
s/^\([^_][^_]*\).*__\(.*_\)\{0,1\}\([^,]*\),[^,]*,[^_]*,\1,.*/\3/p
s/^[^_]*__//;s/$/,/
y/_\n/\n_/
/\n/!H
' Ref.txt Seq.txt
참고: 이는 bash
여기에 지정된 매개변수의 순서와 개수를 사용하여 명령줄에서 실행됩니다.
Perl
정규식을 사용하지 않고도 여기에서 사용할 수도 있습니다.
$ perl -F, -lane '
if ( @ARGV ) {
$h{$_} = $F[0] for @F[2..$#F];
next;
}
my $seq = $_;
my($k) = grep { ! index($seq, $_) } keys %h;
print $h{$k};
' Ref.txt Seq.txt
답변3
나처럼 게으른 사람이라면 배열과 루프를 처리하고 이를 도구에 맡기고 싶지 않을 것입니다. 이것이 바로 내가 sed
이 Ref.txt
줄(쉼표로 식별)을 예약된 공간에 두는 것을 선호하는 이유입니다 H
. 실제로 패턴이 항상 두 개의 쉼표 사이에 있다는 것을 알기 위해 또 다른 쉼표를 추가했습니다. 그래서 그것은 합산됩니다 /,/{s/$/,/;H;d;}
.
이제 의 각 줄에 대해 Seq.txt
참조 힙을 예약된 공간에 추가하고 명령이 패턴을 힙에서 찾은 패턴으로 바꾸도록 G
합니다 . s
정규식은 일반적으로 읽는 것보다 작성하는 것이 더 쉽습니다.
이제 패턴 공간을 살펴보겠습니다.
ABCDEFG\n\nABCDEFG,15147,ABC,ABCD,ABCDE\nHIJKLMN,500,HIJKLM,HIJKL,HIJK
\_____/ \_____/ \_/
replace by this if match
- 교체할 부품은 처음(
^
)에 위치하고, 일치하는 부품([A-Z]+
)과 전후의 일부 부품([A-Z]*
) 이 있습니다. - 교체는 개행 문자와 쉼표 사이의 순서입니다.
\n[A-Z]*,
- 일치 항목은 첫 번째 부분에서 역참조된 두 개의 쉼표 사이의 패턴입니다.
,\1,
전체적으로 이것은 다음과 같습니다.
sed -E '/,/{s/$/,/;H;d;};G;s/^[A-Z]*([A-Z]{1,})[A-Z]*\n.*\n([A-Z]*),[A-Z0-9,]*,\1,.*/\2/;P;d' Ref.txt Seq.txt