레이블이 이맥스인 게시물을 표시합니다. 모든 게시물 표시
레이블이 이맥스인 게시물을 표시합니다. 모든 게시물 표시

2011년 2월 10일 목요일

이맥스의 정규 표현식 치환 기능

드디어 매스매티카 8을 쓸 수 있게 되었다. 이전 버전에서 작업하던 파일을 열어 실행하니 왠 걸. 떡하니 에러가 뜬다.

매스매티카 8.0의 변경사항으로 인해 발생하는 오류


난 매스매티카를 주로 이론적 분석, 즉 수식전개 등에 사용하는데, 종종 중간 결과를 수식번호 형식으로 저장해 놓는다. 해당 장(chapter)과 각 장에서의 수식번호를 나타내는 eq15\[Dash]8과 같은 형식의 변수명을 사용하는데, 여기서 문제가 발생했다. 이전 버전까지는 eq15-8을 단일 변수명으로 봤는데, 8.0에서는 이를 eq15, \[Dash], 8의 곱으로 인식한다.

어차피 각 장은 별도의 파일에 저장하고 있으므로, 변수명에서 장 번호를 없애기로 했다. 그러면 변수명을 eq8과 같이 \[Dash] 없이 쓸 수 있으므로 문제를 해결할 수 있다. 파일 마다 많게는 100여개에 이르는 수식번호를 어떻게 일일이 다 바꿀까? 매스매티카에서 하기는 어려울 것 같다. 간단한 방법을 생각해보면, sed를 이용할 수도 있고 이맥스의 치환 기능을 이용할 수도 있겠다. 일단 변환할 문자열의 형태를 알아야 하니, 이 파일을 이맥스에서 열어보자.

이 부분의 해석 방식이 바뀌었다.

해당 부분의 입력이 위와 같이 저장된 것을 알 수 있다. 이제 이러한 패턴을 찾아서 바꾸면 된다. replace-regexp(C-M-%) 명령을 이용하면, 정규 표현식으로 위와 같은 패턴의 문자열을 모두 찾아서 바꿀 수 있다. 위 그림에서 강조한 부분을 나타내는 정규 표현식은 아래와 같다.
RowBox\[{"eq15", "\\\[Dash\]", "[0-9][0-9]*"}\]
하지만, 문제가 하나 있다. 패턴은 이게 맞는데 매번 치환마다 수식번호를 그것에 맞게 바꿔줘야 한다. 그렇지 않으면 모든 수식번호가 하나로 바뀌게 된다. 이건 패턴의 변수 기능을 이용하면 해결할 수 있다. 먼저, 수식번호에 해당하는 부분을 괄호로 둘러싼다. Query replace regexp:에 입력할 정규 표현식은 아래와 같다.
RowBox\[{"eq15", "\\\[Dash\]", "\([0-9][0-9]*\)"}\]
괄호로 둘러싼 부분은 치환된 문자열에서 \1로 불러올 수 있다. 괄호가 두 개 이상이면 \2, \3 등으로 불러올 수 있다. 즉, with:에 입력할 패턴은 아래와 같다.
"eq\1"
일치하는 문자열을 한번에 모두 치환하려면 Query replacing이 진행 중일 때, !를 입력하면 된다.

replace-regexp를이용하여 치환하는 모습

문자열 치환을 마치고, 파일을 저장한다. 이제 수정한 파일을 매스매티카에서 열어보자.

노트북 파일을 매스매티카 외부에서 수정하면 저장된 임시 계산 결과를 이용할 수 없다.

경고창이 하나 뜨는며 살짝 겁을 준다. 잘 읽어보면, 수정된 파일이므로 임시 저장 결과를 이용할 수 없다는 안내이다. 친절하게도 내용에는 문제가 없을 거라며 안심 시켜준다. OK를 클릭해서 넘어간다. 수식을 다시 실행해보면, 문제가 해결된 것을 볼 수 있다.

이맥스와 정규 표현식을 이용하면 문제가 되는 부분을 한 번에 모두 치환할 수 있다.

2010년 12월 6일 월요일

리눅스와 윈도의 줄바꿈 차이

글을 입력하면서 커서가 화면의 오른쪽 끝에 이르면 '줄바꿈'을 해야 한다. 리눅스와 윈도 모두 '줄바꿈'을 할 때 누르는 키는 '엔터(Enter)'이고 화면에서 나타나는 모양새는 같은데, 내부적인 처리에는 차이가 있다.

윈도는 옛 타자기 시절의 습관을 고스란히 옮겨 놓은 낭만적인 방식을 택한다. 타자기를 사용하던 시절엔 입력하는 글의 줄을 바꾸려면 두 가지 동작이 필요했다. 먼저, 사용자가 글자를 입력함에 따라 종이를 왼쪽으로 옮겨주는 캐리지(carriage)라는 부품을 오른쪽 끝으로 밀어야 한다. 그런 다음 종이를 조금 위로 올려서 다음 줄의 첫 부분에 활자가 닿을 수 있도록 조정해야 한다. 캐리지를 오른쪽 끝으로 되돌려 놓는 동작은 컴퓨터에서 커서의 위치를 왼쪽 끝으로 되돌려 놓는 동작에 해당하고, 이를 복귀(carriage return)이라고 한다. 문자열 표기(string notation)로는 '\r'로 나타낸다. 종이를 위로 올리는 동작은 현재 커서가 있는 줄의 아래에 입력 가능한 줄을 삽입하고 커서를 한 칸 아래로 내리는 동작에 해당하며 이를 새줄(new line)이라고 한다. 문자열 표기로는 '\n'으로 나타낸다. 실제로 글을 입력할 때 줄을 바꾸려면 엔터 키만 누르지만, 문서의 각 줄 끝에는 '\r\n'이 들어간다.

리눅스(유닉스 계열)는 컴퓨터에 적합한 실용적인 방식을 택한다. 타자기는 기계적인 한계 때문에 '복귀'와 '새줄'이라는 동작을 차례로 해야 했지만, 컴퓨터에서는 굳이 그럴 필요가 없다. 그래서 '줄바꿈'이라는 표시로 '\n'만을 사용한다.

모든 비표준이 그렇듯이, 이러한 차이는 리눅스와 윈도를 오가며 문서를 작성하다 보면 불편한 점을 만든다. 윈도에서 작성한 문서를 리눅스에서 보면 모든 줄 끝에 '^M'이라는 문자가 나타난다. 리눅스는  '\n'만을 '줄바꿈'으로 문자로 인식하고, '\r'은 해당 꺽쇠 표기(caret notation)인 '^M'로 화면에 표시하는 것이다.

윈도 줄바꿈 형식을 사용한 문서를 유닉스 계열의 줄바꿈 형식으로 열면 ^M 문자를 볼 수 있다.

이건 그나마 나은 편이다. 리눅스에서 작성한 문서를 윈도에서 보면 문서의 모든 내용이 한 줄에 표시된다. 윈도에서 줄바꿈으로 인식하는 '\r\n'이라는 제어 문자가 없으니 한 줄에 모든 내용을 표시해버린다.

유닉스 계열의 줄바꿈 형식을 사용한 문서를 윈도에서 열면 줄바꿈이 되지 않는다.

요즘은 편집기가 똑똑해져서 '줄바꿈' 제어 문자가 뭐로 되어 있든지 알아서 잘 처리해주지만, 때로 문제가 되기도 한다. 한 문서에 여러 가지 '줄바꿈' 제어 문자가 들어 있으면, 편집기가 이를 잘 처리하지 못하기도 하고, 시스템 환경과 다른 '줄바꿈' 문자 때문에 스크립트 프로그램이 이상한 오작동을 하기도 한다. 그렇다면, 윈도 방식의 줄바꿈으로 된 문서를 리눅스 방식의 줄바꿈으로 바꾸려면 어떻게 해야 할까?

쉘에서 손쉽게 바꾸는 방법은 아래와 같다.
$ cat <FileName> | tr -d '\r' > out; mv out <FileName>
이맥스에서 두 가지 방법으로 할 수 있다. 첫 번째는 ^M을 공백으로 치환하는 방법이다. C-Home으로 버퍼의 첫 부분으로 간 다음 아래 명령을 실행한다.
M-% C-q C-m RET RET !
C-q는 입력 버퍼에 제어 문자를 입력하게 해주는 키이다. 두 번째로 현재 버퍼의 코딩 방식을 바꿔주는 방법이 있다.
M-x set-buffer-file-coding-system을 입력하거나 C-x RET f를 입력해서, 미니버퍼에
Coding system for saving file (default nil):
이 뜨면, unix를 입력한다.

2010년 7월 20일 화요일

이맥스의 파이썬 모드에서 주석처리

이맥스의 파이썬 모드(M-x python-mode)를 사용하다 보면, 중요한 기능 하나가 메뉴에 없는 것을 알 수 있다. 바로 주석 처리 기능인데, 사실 메뉴에만 없지 이미 모든 프로그램 모드에서 제공하는 기능이다. 단축키는 M-; (‘coent-dwim’)이다.

일정 부분을 주석 처리하려면, 주석처리를 시작할 부분에서 C-SPC-SPC로 Transient-mark-mode를 켜고 끝 부분까지 커서를 이동한다. 다음으로, M-;을 누르면 해당 구역이 주석 처리된다. 이미 주석 처리된 부분에서 이렇게 하면 주석이 해제된다.


임의의 줄에서 M-;을 누르면 줄의 맨 끝에서 주석을 시작한다.