2개의 파일이 있습니다. file1과 file2의 필드 1, 2, 4, 5가 모두 일치하면 출력 파일에 file1과 file2의 전체 줄을 인쇄하고 싶습니다.
파일 1:
sc2/80 20 . A T 86 F=5;U=4
sc2/60 55 . G T 76 F=5;U=4
sc2/68 20 . T C 71 F=5;U=4
sc2/24 24 . T G 31 F=5;U=4
파일 2:
sc2/99 84 . C G 61 F=5;U=4
sc2/80 20 . A T 30 F=5;U=4
sc2/60 40 . G T 76 F=5;U=4
sc2/30 20 . T C 71 F=5;U=4
sc2/24 24 . T G 91 F=5;U=4
예상 출력:
sc2/80 20 . A T 86 F=5;U=4
sc2/80 20 . A T 30 F=5;U=4
sc2/24 24 . T G 31 F=5;U=4
sc2/24 24 . T G 91 F=5;U=4
저는 이 분야를 처음 접했고 도움을 주셔서 감사합니다.
답변1
다차원 배열을 사용할 수 있습니다.
awk 'FNR==NR{a[$1,$2,$4,$5]=$0;next}{if(b=a[$1,$2,$4,$5]){print b;print}}' file1 file2
FNR
NR
(파일 레코드 수) 는 awk가 첫 번째 파일을 처리할 때의 값 과 같습니다 .
a[$1,$2]=$0
a[$1 SUBSEP $2]=$0
or 와 같고 a[$1"\034"$2]=$0
, ($1,$2)in a
or 와 같습니다.($1 SUBSEP $2)in a
($1"\034"$2)in a
와 같이 .if if(b=a[$1,$2,$4,$5]){print b;print}
로 바꿀 수도 있습니다 .if(($1,$2,$4,$5)in a){print a[$1,$2,$4,$5];print}
!("index" in a)
a["index"]
a["index"]=""
답변2
당신이 Perl이나 Python 솔루션을 원하지 않는다고 말한 것을 알고 있지만 다른 사람들에게는 유용할 수 있습니다(생물정보학을 하고 있다면 실제로 이러한 언어 중 하나를 배워야 합니다).
perl -ane '$f=$F[0].$F[1]; print "$k{$f}$_" if $k{$f}; $k{$f}=$_;' file1 file2
설명하다:
이 -a
옵션을 사용하면 Perl이 입력을 @F
배열로 분할하게 됩니다. -n
즉, 입력 파일을 한 줄씩 읽는다는 의미입니다. -e
즉, "명령줄에서 제공한 스크립트를 실행합니다"라는 뜻입니다.
따라서 는 첫 번째( ) 필드와 두 번째( ) 필드를 연결한 것으로 설정됩니다 $f
. 현재 줄( )을 key로 호출되는 해시(Perl의 연관 배열)에 값으로 저장하는 것을 나타냅니다. 파일을 읽을 때 현재 줄과 값이 있으면 인쇄합니다. 즉, 동일한 두 개의 첫 번째 필드가 있는 행을 본 경우 해당 행과 현재 행을 인쇄합니다.$F[0]
$F[1]
$k{$f}=$_
$_
k
$f
$k{$f}
답변3
두 파일의 순서를 바꾸지 않고 교차점을 인쇄하시겠습니까(따라서 교차점이 설정되지 않음)? 내가 올려다 볼게문자열 유사성 알고리즘각 줄을 문자로 처리합니다. 어떤 문자(행)가 동일하고 다른지 추적하려면 알고리즘을 수정해야 합니다. 가장 큰 문제는 순서는 중요하지만 위치는 중요하지 않다는 것입니다. 또한 관심 없는 필드를 제거하도록 데이터를 다시 작성하면 데이터를 더 쉽게 관리할 수 있습니다. (또는 이러한 필드를 무시하는 비교 함수를 작성하십시오.)
Python이나 Perl을 고려해 보셨나요? 생물정보학 분야에서 인기가 높다고 들었습니다. 이것은 실제로 프로그래밍 작업처럼 보입니다.
답변4
각 파일에 고유한 항목이 있어야 한다고 보장할 수 있는 경우. 파일을 연결하여 파일을 정렬합니다 sort -u
. 다시 정렬 -u
하고 중복된 항목을 검색하세요.
이 작은 대본을 작성할 수는 있지만 내 생각으로는 할 수 없습니다. 하지만 내 접근 방식을 고려하면 이는 어렵지 않습니다.
이제 내 앞에 콘솔이 생겼습니다. 여기 있어요:
rm -rf all; sort -u file1 > all; sort -u file2 >> all
sort all | uniq --all-repeated=separate -w 32
이미 정렬되어 있고 중복된 항목이 없으면 file1
file2
다음 명령을 사용할 수 있습니다.
sort -m file1 file2 | uniq --all-repeated=separate -w 32
아, 전체 행을 비교해보니 정확히 말씀하신 내용이 아닌 것 같네요. 어쩌면 다른 누군가가 이것이 유용하다고 생각할 수도 있습니다.