변수에 개행 문자(POSIX)가 포함되어 있는지 테스트

변수에 개행 문자(POSIX)가 포함되어 있는지 테스트

나는 일부 쉘이 이런 종류의 테스트를 허용한다는 것을 알고 있습니다.

t() { [[ $var == *$'\n'* ]] && res=yes || res=no
      printf '%s ' "$res";
    }

var='ab
cd'
t
var='abcd'
t
echo

실행 시:

$ bash ./script
yes no
  1. POSIX에 해당하는 작업은 무엇입니까(대시)

  2. 다음 테스트 방법은 신뢰할 수 있습니까?

    nl='
    '
    
    t() {  case "$var" in
               *$nl* ) res=yes ;;
               * ) res=no ;;
           esac
           printf '%s ' "$res"
         }
    
    var='ab
    cd'
    t
    var='abcd'
    t
    echo
    

답변1

변수에 새 줄을 넣고 패턴 일치를 수행할 수 있습니다 case.

$ cat nl.sh
#!/bin/sh
nl='
'
case "$1" in
    *$nl*)  echo has newline ;;
    *)      echo no newline  ;;
esac

$ dash nl.sh $'foo\nbar'
has newline
$ dash nl.sh $'foobar'
no newline

줄 바꿈을 만드는 또 다른 방법은 다음과 같습니다.

nl=$(printf "\nx"); nl=${nl%x}

명백한 명령 대체는 대체가 후행 줄 바꿈을 제거하기 때문에 작동하지 않습니다.

답변2

예,

nl='
'
case $var in
  (*"$nl"*) echo yes;;
  (*)       echo no;;
esac

case(원칙적으로 패턴으로 처리되기를 원하지 않는 한 패턴 내에서 모든 변수 확장을 인용하고 싶습니다 . 하지만 여기서는 $nl와일드카드가 포함되지 않기 때문에 차이가 없습니다.)

또는

case $var in
  (*'
'*) echo yes;;
  (*) echo no;;
esac

모든 것이 잘 작동하고 POSIX와 호환되어야 하며 이것이 제가 사용할 것입니다. s를 제거하면 (이전 Bourne 쉘에서도 작동합니다 .

변수를 설정하는 $nl또 다른 방법 :

eval "$(printf 'nl="\n"')"

알아채다$'\n'POSIX 표준의 다음 버전에 포함될 예정. 최소한 ksh93, zsh, bash, mkshbusybox 및 FreeBSD에서 지원됩니다(2018년 2월 기준).sh

보유한 테스트가 충분한지 여부에 대해 두 경우 모두 테스트했으므로 모든 코드 경로가 테스트됩니다.

현재 POSIX 사양에 명시적으로 지정되지 않은 사항은 *유효한 문자를 형성하지 않는 바이트 시퀀스가 ​​포함된 문자열을 일치시킬지 여부 또는 쉘 변수에 이러한 문자열을 포함할 수 있는지 여부입니다.

실제로 변수는 문자만 포함할 수 있다는 점을 제외하면 yashNUL 바이트(셸이 가능하지 않지만 zsh변수에 저장할 수 있음) 이외의 *$nl*문자열을 포함하는 $nl문자열은 유효한 바이트 시퀀스를 형성하지 않는 문자가 포함되어 있더라도 일치해야 합니다( UTF-8 과 같은 $'\x80').

예를 들어 일부 find구현은 -name "*$nl*"일치하지 않으므로 새 셸을 테스트하고 텍스트(예: 파일 이름)가 보장되지 않는 항목을 처리하려는 경우 이에 대한 테스트 사례를 추가할 수 있습니다. . 다음과 같이:

test=$(printf '\200\n\200')

UTF-8 로케일.

관련 정보