문자열이 이스케이프 시퀀스(\n)로 끝나는지 확인하는 방법

문자열이 이스케이프 시퀀스(\n)로 끝나는지 확인하는 방법

x후행 개행 문자가 있는 변수가 있습니다.

printf -v x 'hello\n'

마지막 문자가 x인지 어떻게 알 수 있나요 \n?

답변1

\n문자가 아닌 문자열의 마지막 문자를 설명하므로 해당 문자가 단일 문자 ( newlineASCII라고도 함 ) 인지 감지하는 방법을 찾고 있습니다 line feed. 문자열이 \두 문자(백슬래시)와 로 끝나는 지 감지하고 싶지 않습니다 n.

상당히 최신 버전의 Bash에서 이를 수행하는 한 가지 방법은 다음과 같습니다.

#!/usr/bin/env bash

printf -v x 'hello\n'

[[ "${x: -1:1}" == $'\n' ]] && echo "Ends in newline"

echo done

${x: -1:1}Bash의 하위 문자열 확장을 사용하여 문자열의 마지막 문자를 반환합니다. 매뉴얼 페이지의 구문은 ${parameter:offset:length}음수 오프셋이 문자열의 시작이 아닌 끝에서 시작된다는 것을 명시하고 있습니다. 또한 다양한 유형의 매개변수 확장과의 혼동을 피하기 위해 첫 번째 와 :사이에 공백이 필요하다고 명시합니다.-1

$'\n'Bash의 "작은따옴표의 특수 변형" 구문을 사용하여 "ANSI C 표준"에 지정된 문자를 나타냅니다.

이 옵션은 내장 명령에서 stdout 대신 지정된 변수에 출력을 쓰는 데 printf사용됩니다 . 이 옵션은 모든 셸에서 작동하지 않을 수 있습니다(외부 바이너리 -v에서도 작동하지 않음 ). 문자는 printf직접 printf지원되며 \n"특수 변형" 구문이 필요하지 않습니다.

작성된 대로 이는 변수 끝의 개행에서만 작동하지만 이것이 바로 여러분이 요구하는 것입니다. 다른 제어 문자 및/또는 문자열의 다른 위치를 확인하려면 특정 요구 사항에 따라 다른 구문이 필요합니다.

답변2

POSIX 셸에서:

case "$string" in
  (*'
')    echo The string ends in a newline character;;
  (*) echo It does not;;
esac

$'...'ksh93 인용 형식을 지원하는(그리고 POSIX 표준의 다음 버전에서 지정될 ) bash를 포함하는 셸에서 sh다음 명령을 사용하면 더 쉽게 읽을 수 있습니다.

case "$string" in
  (*$'\n') echo The string ends in a newline character;;
       (*) echo It does not;;
esac

지원되지 않는 쉘의 경우 다른 옵션은 $'...'개행 문자를 전역 변수에 저장하는 것입니다.

NL='
'

또는

eval "$(printf ' NL="\n" CR="\r" TAB="\t" FF="\f" BS="\b" BEL="\a" ')"

각 제어 문자에 대한 변수를 구성하고 다음을 사용하십시오.

case "$string" in
  (*"$NL") echo The string ends in a newline character;;
  (  *   ) echo It does not;;
esac

일부 셸(최소 ksh93, zsh, bash, mksh)에서는 다음을 수행할 수도 있습니다.

if [[ "$string" = *$'\n' ]]; then
  echo The string ends in a newline character
else
  echo It does not;;
fi

매개변수의 마지막 문자인 POSIXly를 얻으려면 패턴 제거 연산자를 남용할 수 있습니다.

if [ "${string#"${string%?}"}" = "$NL" ]; then
  echo The string ends in a newline character
else
  echo It does not;;
fi

zsh 또는 yash에서는 다음을 수행할 수 있습니다.

if [ "${string[-1]}" = "$NL" ]; then...

또는 다음과 같이 단순화되었습니다 zsh.

if [[ $string[-1] = $'\n' ]]; then...

해당 배열은 희소 배열이고 $var이미 축약형 ${var[0]}이며 다차원 배열을 지원하기 때문에 ksh93은 문자열 또는 배열 분할에 대해 어색한 구문을 도입했습니다.

if [[ ${string:${#string}-1} = $'\n' ]]; then...

bash(다차원 배열은 없지만 ksh에서 배열 디자인의 대부분을 복사함)는 이를 2.0에서 복제했습니다.

Bash에서 오프셋은 음수일 수도 있으며 끝부터 계산됩니다(또는 4.​​2에서 시작하는 길이도 가능). 그러나 ${var:-default}Bourne 쉘의 다른 모든 것과 마찬가지로 산술 표현식 다음의 첫 번째 문자는 (nor ) :가 될 수 없으므로 -or 또는 ...가 필요합니다.+${string: -1}${string:(-1)}S{string:0-1}

ksh93은 이것을 ksh93m에서 복제했으며, mksh와 마찬가지로 zsh도 결국 ${var:offset[:length]}ksh 호환성에 대한 지원을 추가했습니다(zsh의 csh 스타일 지원으로 인해 더 많은 제한이 있었지만 ${var:modifiers}).

관련 정보