해당 쌍 없이 두 줄 세트를 인쇄하려고 합니다. 결국 이 줄을 삭제하고 싶습니다.
예:
NM00123_rn5_0_1_2
XXXXXXXXXXXXXXXXXXXXXXXXXXX
NM00123_mm10_0_1_2
XXXXXXXXXXXXXXXXXXXXXXXXXXXX
NM00124_rn5_0_1_3
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
NM00124_mm10_0_1_3
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
NM00125_rn5_0_1_4
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
NM00126_rn5_0_1_5
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRr
NM00126_mm10_0_1_5
RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRR
NM으로 시작하는 줄이 제목이고, 다음 줄은 일련의 문자로 구성됩니다. 쌍의 헤더 행은 rn5 및 mm10을 제외한 모든 위치에서 일치합니다. 나는 rn5 및 mm10 일치 전후의 NM 헤더 번호인 4개 행 세트를 유지하고 싶습니다. 따라서 위의 예에서 rn5의 1행 헤더는 mm10의 3행 헤더와 일치하므로 유지됩니다. 그러나 9행의 rn5 헤더는 해당 쌍이 아니므로 다음을 사용하여 헤더를 인쇄합니다. 그리고 다음 줄 순서. 나는 궁극적으로 동일한 수의 rn5 및 mm10 항목을 포함하는 파일을 갖고 싶습니다.
저는 Unix를 처음 사용하는데, 여러분의 도움에 진심으로 감사드립니다. 감사해요.
예상되는 결과:
위 항목 중 해당 행이 없습니다. 이 경우:
NM00125_rn5_0_1_4
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
답변1
이것은 awk의 다소 복잡한 버전입니다. Steeldriver의 sed 버전과의 몇 가지 차이점은 다음과 같습니다.
mm10
기록이 기록되는 순서에 대해rn5
어떠한 가정도 하지 않습니다.rn5
누락된 레코드를 처리할 수 있습니다.- 일치하지 않는 레코드를
stderr
. - 추가 코드는 다음과 같습니다 :-)
다음을 통해 실행할 수 있습니다.
awk -f my_program.awk infile
암호:
# find and store a header
/^NM.*/ { header = $0; next }
# we found an mm10 line
header ~ /_rn5/ {
# get the mm10 line that matches this rn5
mm_match = header
sub("_rn5", "_mm10", mm_match)
# if we have a previous mm10, then print the pair
if (mm_match in headers) {
print header
print
print mm_match
print headers[mm_match]
delete headers[mm_match]
} else {
headers[header] = $0
}
next
}
# we found an mm10 line
header ~ /_mm10/ {
# get the rn5 line that matches this mm10
mm_match = header
sub("_mm10", "_rn5", mm_match)
# if we have a previous rn5, then print the pair
if (mm_match in headers) {
print mm_match
print headers[mm_match]
print header
print
delete headers[mm_match]
} else {
headers[header] = $0
}
next
}
또한 이 코드를 파일 끝에 추가하여 일치하지 않는 줄을 다음으로 출력할 수 있습니다 standard error
.
# The END block is here just to output anything that was unmatched
END {
# dump the unmatched to stderr
for (header in headers) {
print header > "/dev/stderr"
print headers[header] > "/dev/stderr"
}
}
다음을 통해 실행할 수 있습니다.
awk -f my_program.awk infile > outfile 2> unmatched
outfile
요청된 출력(표준 출력을 통해)을 에 출력 하고 나머지 입력(표준 오류를 통해)을 에 출력합니다 unmatched
. 다양한 I/O 리디렉션에 대한 자세한 내용은 다음 장을 참조하세요.리디렉션Bash 참조 매뉴얼에 있습니다.
답변2
나생각하다요청하신 내용은
- 4줄 버퍼를 유지하고
- 다음 내용
rn5
(다음 개행까지)이 뒤따르는 내용mm10
(다음 개행까지)과 일치하면 인쇄하고 다시 시작하세요.
이는 추악한 접근 방식일 수 있지만 GNU 용어로 설명하면 다음과 같습니다 sed
.
$ sed -n -e :a \
-e '$!N; /rn5_\(.*\)\n.*\n.*mm10_\1\n/ {p;b}' \
-e '/.*\n.*\n.*\n/ D' \
-e ba infile > outfile
$ diff outfile infile
8a9,10
> NM00125_rn5_0_1_4
> zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz