FreeBSD에서 파일에 ESC 제어 문자를 삽입하는 방법은 무엇입니까?

FreeBSD에서 파일에 ESC 제어 문자를 삽입하는 방법은 무엇입니까?

Fortran 주석을 두 개의 이스케이프 명령(ESC+E 및 ESC+F)으로 래핑하고 싶습니다. 이는 접두사 및 접미사 !뿐만 아니라 줄 끝에서 시작하고 끝나는 주석을 감지하는 것을 의미합니다 .ESC+EESC+F

첫 시도

$ echo "test line  ! Enclose this in ESC commands" | sed 's/\(!.*\)/\033E\1\033F/'
test line  033E! Enclose this in ESC commands033F

ESC 문자 자체는 생성되지 않고 대신 033이 표시됩니다.

두 번째 시도

$ echo "test line  ! Enclose this in ESC commands" | sed $'s/\(!.*\)/\033E\1\033F/'
sh: Syntax error: Bad escape sequence

시스템 세부정보

운영 체제: FreeBSD 12.
껍데기:sh.
Seder:sed.

답변1

실패한 시도

여기서 이해해야 할 두 가지 수준이 있습니다. 먼저 쉘이 입력을 처리한 다음 이를 Sed에 전달합니다.

  •  sed 's/\(!.*\)/\033E\1\033F/'
    

    작은따옴표는 안에 있는 모든 문자의 문자 그대로의 의미를 유지하므로 첫 번째 시도에서 Sed는 따옴표 사이의 모든 문자를 가져옵니다.

    그러나 Sed가 \033ASCII Octal 033(ESC)을 이해하지 못하기 때문에 실패합니다. 라고 짐작하셨을 수도 있지만sed 매뉴얼그것에 대해 아무 말도하지 않았습니다.

  •  sed $'s/\(!.*\)/\033E\1\033F/'
    

    $'...'구성은 ANSI C 참조입니다. 그러면 쉘이 $'\033'ESC 문자로 변환되기 때문에 이는 좋은 생각입니다. 하지만,Sh FreeBSD 매뉴얼 유효한 백슬래시 시퀀스가 ​​포함된 목록

    백슬래시로 시작하는 다른 문자열은 오류입니다.

    목록 \(또는 \)? 아니요, 따라서 오류 메시지가 나타납니다. 또한 \1Sed로 보내야 하는 내용도 ASCII Octal 001(SOH)로 해석되는데 이는 확실히 사용자가 원하는 것이 아닙니다.

해결책

아래 옵션 1과 2의 경우 \033간단히 로 쓸 수도 있습니다 \e.

  1. ANSI 인용 이스케이프 \033시퀀스만 사용하고 나머지는 일반 인용으로 남겨둡니다.

    sed 's/\(!.*\)/'$'\033''E\1'$'\033''F/'
        ^^^^^^^^^^^^       ^^^^^       ^^^^
                    ^^^^^^^     ^^^^^^^
    
  2. 일치하는 문자열 전체를 캡처하는 데 캡처 그룹이 필요하지 않습니다. 이것이 &기본값입니다.

    sed $'s/!.*/\033E&\033F/'
    
  3. (POSIX 호환) ESC를 생성하려면 Printf를 사용하세요. 하나를 선택하세요

    esc=$(printf '\033'); sed "s/!.*/${esc}E&${esc}F/"
    sed "s/!.*/$(printf '\033')E&$(printf '\033')F/"
    
  4. (POSIX 호환) awk.

    awk '{sub(/!.*/, "\033E&\033F"); print}'
    

관련 정보