
Fortran 주석을 두 개의 이스케이프 명령(ESC+E 및 ESC+F)으로 래핑하고 싶습니다. 이는 접두사 및 접미사 !
뿐만 아니라 줄 끝에서 시작하고 끝나는 주석을 감지하는 것을 의미합니다 .ESC+E
ESC+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
시스템 세부정보
답변1
실패한 시도
여기서 이해해야 할 두 가지 수준이 있습니다. 먼저 쉘이 입력을 처리한 다음 이를 Sed에 전달합니다.
-
sed 's/\(!.*\)/\033E\1\033F/'
작은따옴표는 안에 있는 모든 문자의 문자 그대로의 의미를 유지하므로 첫 번째 시도에서 Sed는 따옴표 사이의 모든 문자를 가져옵니다.
그러나 Sed가
\033
ASCII Octal 033(ESC)을 이해하지 못하기 때문에 실패합니다. 라고 짐작하셨을 수도 있지만sed 매뉴얼그것에 대해 아무 말도하지 않았습니다. -
sed $'s/\(!.*\)/\033E\1\033F/'
이
$'...'
구성은 ANSI C 참조입니다. 그러면 쉘이$'\033'
ESC 문자로 변환되기 때문에 이는 좋은 생각입니다. 하지만,Sh FreeBSD 매뉴얼 유효한 백슬래시 시퀀스가 포함된 목록백슬래시로 시작하는 다른 문자열은 오류입니다.
목록
\(
또는\)
? 아니요, 따라서 오류 메시지가 나타납니다. 또한\1
Sed로 보내야 하는 내용도 ASCII Octal 001(SOH)로 해석되는데 이는 확실히 사용자가 원하는 것이 아닙니다.
해결책
아래 옵션 1과 2의 경우 \033
간단히 로 쓸 수도 있습니다 \e
.
ANSI 인용 이스케이프
\033
시퀀스만 사용하고 나머지는 일반 인용으로 남겨둡니다.sed 's/\(!.*\)/'$'\033''E\1'$'\033''F/' ^^^^^^^^^^^^ ^^^^^ ^^^^ ^^^^^^^ ^^^^^^^
일치하는 문자열 전체를 캡처하는 데 캡처 그룹이 필요하지 않습니다. 이것이
&
기본값입니다.sed $'s/!.*/\033E&\033F/'
(POSIX 호환) ESC를 생성하려면 Printf를 사용하세요. 하나를 선택하세요
esc=$(printf '\033'); sed "s/!.*/${esc}E&${esc}F/" sed "s/!.*/$(printf '\033')E&$(printf '\033')F/"
(POSIX 호환) awk.
awk '{sub(/!.*/, "\033E&\033F"); print}'