전체 파일의 모든 줄에서 특정 컨텍스트의 문자를 바꾸는 방법은 무엇입니까?

전체 파일의 모든 줄에서 특정 컨텍스트의 문자를 바꾸는 방법은 무엇입니까?

다음과 같은 형식의 영어 구문 수백 개가 포함된 큰 파일이 있습니다.

\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&&!--cawk논리를 구현하는 일반적인 관용어입니다 while getline.인용하다.

이 조건 이후의 동작은 1에서 0으로 감소할 때만 수행됩니다.

리터럴을 일치시킬 때 일치 후 세 번째 줄에서만 실행되도록 '\phrase'설정하고 c=3이는 모든 일치에 대해 반복됩니다.gsub()

답변3

Emacs를 사용하고 계시기 때문에...

악의 길/빔

이미 evil-modeVim을 설치했거나 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 eC-u 10000C-M-sC-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-regionEmacs 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/ɹ/gPOSIX 호환 구현에서도 작동 하지만 멀티바이트 문자를 지원하지 않는 구현( UTF-8 경우) 에서도 작동하므로 이식성이 더 뛰어납니다 . ; 단일 바이트로 인코딩되는 문자 인코딩을 찾을 수 없습니다 .sedɹs/r/ɹ/gsedɹɹ

ɹ사용자의 로케일에서 올바르게 인코딩 하려면 zsh다음을 수행하십시오.

sed $'/^\\\\phrase$/{n;n;n;s/r/\u0279/g;}'

사용자 로케일에서 \u0279해당 문자의 인코딩 으로 확장됩니다.ɹ


¹이제 $'\uXXXX'일부 다른 셸에서는 이를 지원하지만 일부 셸에서는 명령이 실행되는 sed로케일 . ksh93에서는 사용자의 로케일에 관계없이 항상 UTF-8로 확장됩니다. 로케일의 문자 세트에서 해당 문자를 사용할 수 없는 경우에도 다른 쉘은 다르게 작동합니다. 오류가 발생하게 됩니다zsh

관련 정보