
다음과 같은 형식의 영어 구문 수백 개가 포함된 큰 파일이 있습니다.
\phrase
{. . . * * }
{I shoul-d've stayed home.}
{aɪ ʃʊd‿əv ˈsteɪd ˈhoʊm.} <- only replace on this line
\phrase
{ . . * }
{Did you eat?}
{dɪdʒjʊʷˈit? ↗} <- only replace on this line
\phrase
{ * . * . * . . . * . }
{Yeah, I made some pas-ta if you're hun-gry.}
{ˈjɛə, aɪ ˈmeɪd səm ˈpɑ stəʷɪf jər ˈhʌŋ gri.} <- only replace on this line
LaTeX .tex
파일입니다. r
각 음성 기호(음성 기호는 \phrase
해당 줄 다음 세 줄마다 의미) 의 모든 문자를 기호(16진수 코드)로 바꾸고 싶습니다.ɹ
U+0279
Emacs에서 수동으로 수행하는 것은 나에게 번거롭습니다. 어떻게든 이 줄을 찾아 자동으로 교체할 수 있는 방법이 있는지 궁금합니다.
예외 없이 모든 r
문자를 바꿔야 ɹ
하지만 음성 기호만 교체해야 하며 r
영어/비음역 텍스트는 그대로 유지됩니다.
스크립트 등을 사용하여 이를 수행할 수 있습니까? 내 문서에는 줄바꿈이 없으므로 전사는 항상 \phrase
. 감사합니다!
답변1
awk 버전(한 줄에 넣을 수 있는 메타 파일이 필요함)
awk '/\\phrase/ { p=NR ; }
NR == p+3 { gsub("r","ɹ") ; }
{print;} ' old-file.tex > new-file.tex
어디
/\\phrase/ { p=NR ; }
발생하는p
모든 줄 번호 로 설정됩니다\phrase
NR == p+3 { gsub("r","ɹ") ; }
그런 다음 라인 3에서 교체를 수행하십시오.{print;}
모든 줄을 인쇄합니다.
다음은 샘플을 제공합니다. (참고 ɹeplace
)
\phrase
{. . . * * }
{I shoul-d've stayed home.}
{aɪ ʃʊd‿əv ˈsteɪd ˈhoʊm.} <- only ɹeplace on this line
\phrase
{ . . * }
{Did you eat?}
{dɪdʒjʊʷˈit? ↗} <- only ɹeplace on this line
\phrase
{ * . * . * . . . * . }
{Yeah, I made some pas-ta if you're hun-gry.}
{ˈjɛə, aɪ ˈmeɪd səm ˈpɑ stəʷɪf jəɹ ˈhʌŋ gɹi.} <- only ɹeplace on this line
답변2
awk 'c&&!--c {gsub(/r/,"ɹ")} /\\phrase/ {c=3} 1' file > newfile
c&&!--c
awk
논리를 구현하는 일반적인 관용어입니다 while
getline
.인용하다.
이 조건 이후의 동작은 1에서 0으로 감소할 때만 수행됩니다.
리터럴을 일치시킬 때 일치 후 세 번째 줄에서만 실행되도록 '\phrase'
설정하고 c=3
이는 모든 일치에 대해 반복됩니다.gsub()
답변3
Emacs를 사용하고 계시기 때문에...
악의 길/빔
이미 evil-mode
Vim을 설치했거나 Vim으로 전환했다면 다음을 수행할 수 있습니다:
:g/^\\phrase/+3s/r/ɹ/g
이것이 가장 간단합니다.
키보드 매크로 모드
기존 Emacs를 계속 사용하면서 키보드 매크로를 사용할 수 있습니다.C-x ( C-M-s ^\\phrase Enter C-n C-n C-n C-a C-space C-e C-M-% r Enter ɹ Enter ! C-x ) C-u 2 C-x e
C-x (
매크로 시작, C-x )
매크로 종료, C-x e
매크로 실행 C-u 2
/ 매크로가 2번 실행되도록 C-2
변경합니다 . 계산을 원하지 않으면 큰 숫자를 사용할 수도 있습니다. 정규식을 검색해 보세요. 3개 행 아래로 이동하여 해당 행을 선택한 후 바꾸기를 선택하세요. 무엇을 교체할지 묻는 메시지가 나타나면 선택 항목의 모든 교체를 수락하는 것을 의미합니다.C-x e
C-u 10000
C-M-s
C-M-%
!
엘립스 로드
*scratch*
버퍼를 열고 실행할 수도 있습니다 ( C-M-x
코드 위에 커서를 놓습니다).
(with-current-buffer "foo"
(goto-char (point-min))
(while (re-search-forward "^\\\\phrase" nil t)
(forward-line 3)
(replace-string-in-region "r" "ɹ" (point) (line-end-position))))
foo
이 작업을 수행하려는 버퍼의 이름은 어디에 있습니까?
편집: replace-string-in-region
Emacs 28.1(작성 당시 최신 버전)에 도입되었습니다. 이전 Emacs를 사용하는 경우 대신 다음을 사용할 수 search-forward
있습니다 replace-match
.
(with-current-buffer "foo"
(goto-char (point-min))
(while (re-search-forward "^\\\\phrase" nil t)
(forward-line 3)
(while (search-forward "r" (line-end-position) t)
(replace-match "ɹ"))))
쉘 명령 필터링 방법
여기에 있는 다른 답변 중 하나와 같이 외부 명령을 통해 Emacs 버퍼를 필터링할 수도 있습니다.C-x h C-u M-| <command> Enter
C-x h
전체 버퍼를 선택합니다. M-|
선택 항목을 필터링하는 명령을 입력하라는 메시지가 표시됩니다. 선택 항목이 임시 버퍼에 저장되는 대신 출력으로 대체되도록 C-u
수정되었습니다 .M-|
답변4
표준 sed
:
sed '/^\\phrase$/{n;n;n;s/r/ɹ/g;}'
y/r/ɹ/
재정의는 문자가 사용자 로케일에서 문자로 처리되는 한 s/r/ɹ/g
POSIX 호환 구현에서도 작동 하지만 멀티바이트 문자를 지원하지 않는 구현( UTF-8 경우) 에서도 작동하므로 이식성이 더 뛰어납니다 . ; 단일 바이트로 인코딩되는 문자 인코딩을 찾을 수 없습니다 .sed
ɹ
s/r/ɹ/g
sed
ɹ
ɹ
ɹ
사용자의 로케일에서 올바르게 인코딩 하려면 zsh
다음을 수행하십시오.
sed $'/^\\\\phrase$/{n;n;n;s/r/\u0279/g;}'
사용자 로케일에서 \u0279
해당 문자의 인코딩 으로 확장됩니다.ɹ
¹이제 $'\uXXXX'
일부 다른 셸에서는 이를 지원하지만 일부 셸에서는 명령이 실행되는 sed
로케일 . ksh93에서는 사용자의 로케일에 관계없이 항상 UTF-8로 확장됩니다. 로케일의 문자 세트에서 해당 문자를 사용할 수 없는 경우에도 다른 쉘은 다르게 작동합니다. 오류가 발생하게 됩니다zsh