변수가 비어 있거나 공백 만 포함되어 있는지 어떻게 테스트 할 수 있습니까?

다음 bash 구문은 param가 비어 있지 않은지 확인합니다.

 [[ ! -z $param ]] 

예 :

param="" [[ ! -z $param ]] && echo "I am not zero" 

출력이없고 괜찮습니다.

하지만 param는 하나 이상의 공백 문자를 제외하고 비어 있으며 대소 문자가 다릅니다.

param=" " # one space [[ ! -z $param ]] && echo "I am not zero" 

“아니요 0 “이 출력됩니다.

공백 문자 만 포함 된 변수를 공백으로 간주하도록 테스트를 변경하려면 어떻게해야합니까?

주석

  • From man test : -z STRING - the length of STRING is zero. $param의 모든 공백을 제거하려면 ${param// /}
  • 사용

  • WOW 간단한 trim() 함수가 내장되어 있지 않습니다. * nix가 전혀 없나요? 너무나도 간단한 것을 달성하기위한 다양한 해킹 방법 …
  • @ADTC $ (sed ‘ s / ^ \ s + | \ s + $ // g ‘ < < < $ string)은 나에게 충분히 간단 해 보입니다. 바퀴를 재발 명하는 이유는 무엇입니까?
  • 더 빛날 수 있기 때문입니다.
  • [[ ! -z $param ]]test ! -z $param.

답변

먼저, -z 테스트 는 명시 적으로 다음에 대한 것입니다.

문자열 길이가 0입니다.

즉, 공백 만 포함하는 문자열은 가 이어서는 안됩니다. div> 길이가 0이 아니므로 -z에서 true입니다.

원하는 것은

패턴 대체 매개 변수 확장 :

[[ -z "${param// }" ]] 

param 변수를 사용하고 패턴 (단일 공백)의 모든 일치 항목을 아무것도없는 것으로 대체하므로 공백 만있는 문자열은 빈 문자열.


작동 방식의 핵심 ${var/pattern/string}pattern의 가장 긴 첫 번째 일치 항목을 string로 바꿉니다. pattern/ (위와 같이)로 시작하면 모든 일치 항목을 대체합니다. 교체 항목이 비어 있으므로 최종 /string 값을 생략 할 수 있습니다.

$ {parameter / pattern / string}

pattern 은 파일 이름 확장에서와 마찬가지로 패턴을 생성하도록 확장됩니다. 매개 변수 가 확장되고 해당 값에 대해 가장 긴 패턴 일치 항목이 문자열 으로 대체됩니다. pattern 이‘/’로 시작하면 pattern 의 모든 일치 항목이 문자열 으로 바뀝니다. 일반적으로 첫 번째 일치 만 교체됩니다. … 문자열 이 null이면 패턴 과 일치하는 항목이 삭제되고 / 다음 패턴 은 생략 될 수 있습니다.

결국 모든 공백을 삭제하기 위해 ${param// }로 끝납니다.

하지만 ksh (원래 위치), zshbash에 있지만 해당 구문은 POSIX이며 sh 스크립트에서 사용해서는 안됩니다.

댓글

  • 사용 sed 그들이 말했습니다 … 단지 echo 그들이 말한 변수 …
  • 흠. ${var/pattern/string} 인 경우 ‘ 슬래시 사이에 공백이있는 [[ -z ${param/ /} ]]이어야합니다. 패턴이되고 뒤에는 문자열이되지 않습니까?
  • @JesseChisholm ” 대체가 비어 있기 때문에 최종 / 및 문자열 값을 생략 할 수 있습니다. div id = “38a048d387”>

; “ string 이 null 인 경우 pattern 의 일치가 삭제되고 / 다음 pattern 이 생략되었습니다. “

  • @MichaelHomer 대답은 [[ -z "${param// }" ]] 확실히 pattern는 비어 있고 replacement string는 단일 공백입니다. 아! 지금 확인합니다. if pattern begins with a slash 그 부분을 놓쳤습니다. 따라서 패턴은 / 이고 문자열은 생략되어 비어 있습니다. 감사합니다.
  • bash 참고 : set -o 명사 설정 (set -u)에서 실행 중이고 매개 변수가 설정되지 않은 경우 (null 또는 공백이 아닌) 바인딩되지 않은 변수 오류가 발생합니다. (set + u; …..)은이 테스트를 면제합니다.
  • 답변

    쉬운 방법 문자열에 인증 된 집합의 문자 만 포함되어 있는지 확인하는 것은 인증되지 않은 문자의 존재 여부를 테스트하는 것입니다.따라서 문자열에 공백 만 포함되어 있는지 테스트하는 대신 문자열에 공백이 아닌 다른 문자가 포함되어 있는지 테스트하십시오. bash, ksh 또는 zsh :

    if [[ $param = *[!\ ]* ]]; then echo "\$param contains characters other than space" else echo "\$param consists of spaces only" fi 

    “공백으로 만 구성”에는 빈 (또는 설정되지 않은) 변수의 대소 문자가 포함됩니다.

    공백 문자를 테스트 할 수 있습니다. [[ $param = *[^[:space:]]* ]]를 사용하여 로케일 설정을 사용하거나 테스트하려는 명시 적 공백 문자 목록을 사용하십시오. [[ $param = *[$" \t\n"]* ]]를 사용하여 공백, 탭 또는 줄 바꿈을 테스트합니다.

    = 내부에있는 패턴에 대해 문자열 일치 id = “b35cd02f6c”>

    는 ksh 확장입니다 (bash 및 zsh에도 있음). Bourne / POSIX 스타일에서case구문을 사용하여 패턴에 대해 문자열을 일치시킬 수 있습니다. 표준 셸 패턴은 대부분의 정규식 구문에서와 같이^대신!를 사용하여 문자 집합을 부정합니다.

    case "$param" in *[!\ ]*) echo "\$param contains characters other than space";; *) echo "\$param consists of spaces only";; esac 

    공백 문자를 테스트하기 위해 $"…" 구문은 ksh / bash / zsh에만 해당됩니다. 이러한 문자를 스크립트에 문자 그대로 삽입하거나 (백 슬래시 + 줄 바꿈이 확장되지 않으므로 줄 바꿈은 따옴표 안에 있어야합니다) 또는 생성 (예 :

    whitespace=$(printf "\n\t ") case "$param" in *[!$whitespace]*) echo "\$param contains non-whitespace characters";; *) echo "\$param consists of whitespace only";; esac 

    댓글

    • 이것은 거의 훌륭하지만 아직 질문에 대한 답변은 아닙니다. 현재 설정되지 않은 또는 빈 쉘 변수와 공백 만 포함하는 변수의 차이점을 알려줄 수 있습니다. 내 제안을 수락하면 쉘 변수를 명시 적으로 테스트하는 다른 답변으로 아직 수렴되지 않은 매개 변수 확장 양식을 추가합니다. 즉, ${var?not set}-해당 테스트를 통과하고 살아남습니다. 예를 들어, *) case와 일치하는 변수가 확실한 답을 얻을 수 있도록합니다.
    • 수정- 사실 이것은 원래 질문에 답변 할 것이지만, 그 이후로 질문의 의미를 근본적으로 변경하여 답변을 무효화하는 방식으로 편집되었습니다.
    • mksh[[ $param = *[!\ ]* ]]가 필요합니다.

    답변

    POSIXly :

    case $var in (*[![:blank:]]*) echo "$var contains non blank";; (*) echo "$var contains only blanks or is empty or unset" esac 

    공백 , 공백 없음 , 비어 있음 , 설정되지 않음 :

    case ${var+x$var} in (x) echo empty;; ("") echo unset;; (x*[![:blank:]]*) echo non-blank;; (*) echo blank esac 

    [:blank:]는 가로 간격 문자 용입니다 (A의 공백 및 탭 SCII, 그러나 아마도 당신의 로케일에 더 많은 것이있을 것입니다. 일부 시스템에는 줄 바꿈없는 공백 (사용 가능한 경우)이 포함되지만 일부는 포함되지 않습니다. 세로 간격 문자 (예 : 줄 바꿈 또는 용지 공급)도 원하는 경우 [:blank:]를 대체합니다. [:space:].

    댓글

    • POSIXly는 (논문의 여지없이 더 나은) 대시.
    • zsh[![:blank:]]에 문제가있는 것 같습니다. :b는 잘못된 수정 자입니다. shksh 에뮬레이트에서 [
    • @cuonglm, 무엇을 시도 했습니까? var=foo zsh -c 'case ${var+x$var} in (x*[![:blank:]]*) echo x; esac'도 괜찮습니다. 찾을 수없는 이벤트는 대화 형 쉘에만 해당됩니다.
    • @St é phaneChazelas : 아, 맞습니다. 대화 형 셸을 사용해 보았습니다. :b 잘못된 수정자는 조금 이상합니다.
    • @FranklinYu, OS / X에서 sh는 는 --enable-xpg-echo-default--enable-strict-posix-default로 구축되어 Unix 호환 ( 탭 출력).

    답변

    작성해야하는 유일한 이유 좋은 스크립팅 언어의 스크립트 대신 셸 스크립트는 극도의 이식성이 가장 중요한 문제인 경우입니다. 레거시 /bin/sh가 유일하게 확신 할 수 있지만 예를 들어 Perl은 Bash보다 크로스 플랫폼에서 사용할 수있는 가능성이 더 많습니다 . 따라서 정말 보편적이지 않은 기능을 사용하는 쉘 스크립트를 작성하지 마십시오. 여러 독점 Unix 공급 업체가 POSIX.1-2001 이전 em 이전에 쉘 환경을 동결했다는 점을 염두에 두십시오. >.

    이 테스트를 수행하는 휴대용 방법이 있지만 tr를 사용해야합니다.

    [ "x`printf "%s" "$var" | tr -d "$IFS"`" = x ] 

    ($IFS의 기본값은 편리하게 공백, 탭, 줄 바꿈입니다.)

    (printf 내장 기능은 그 자체로 휴대 성이 뛰어나지 만 이에 의존하는 것은 echo의 변형을 파악하는 것보다 훨씬 덜 번거 롭습니다.)

    댓글

    • ‘ 약간 복잡합니다.문자열에 특정 문자가 포함되어 있는지 테스트하는 일반적인 이식 방법은 case 를 사용하는 입니다.
    • @Gilles ‘ ‘에 case glob을 쓸 수 있다고 생각하지 않습니다. 비어 있거나 공백 문자 포함하는 문자열을 감지합니다. (정규 표현식을 사용하면 쉬울 수 있지만 case는 정규 표현식을 수행하지 않습니다 ‘. 답변의 구문이 승리했습니다. ‘ 줄 바꿈을 신경 쓰면 작동하지 않습니다.)
    • ‘ 질문이 무엇인지에 대한 대답에 공백을 예로 들었습니다. 물었다. 공백 문자를 테스트하는 것도 ‘ 똑같이 쉽습니다 : case $param in *[![:space:]]*) …. IFS 문자를 테스트하려면 *[$IFS]* 패턴을 사용할 수 있습니다.
    • @mikeserv in a really 진지하게 방어 스크립트를 사용하면 처음에 IFS를 명시 적으로 <space><tab><newline>로 설정 한 다음 다시는 건드리지 않습니다. 저는 ‘가 산만하다고 생각했습니다.
    • 패턴의 변수에 관해서는 모든 Bourne 버전과 모든 POSIX 쉘에서 작동한다고 생각합니다. 케이스 패턴을 감지하고 변수 확장을 해제하려면 추가 코드가 필요하며 ‘ 그 이유를 생각할 수 없습니다. 많은 Bourne 셸에서 실행 된 .profile에 몇 가지 인스턴스가 있습니다. 물론 [$IFS]는 ‘ IFS에 특정 기본값이 아닌 경우 의도 한대로 수행하지 못했습니다. 값 (비어 있거나 설정되지 않음, ] 포함, ! 또는 ^로 시작) .

    답변

    if [[ -n "${variable_name/[ ]*\n/}" ]] then #execute if the the variable is not empty and contains non space characters else #execute if the variable is empty or contains only spaces fi 

    댓글

    • 이것은 단일 공백이 아닌 모든 공백 문자를 제거합니다. 감사합니다.

    답변

    변수가 비어 있는지 또는 공백을 포함하는지 테스트하려면 다음 코드를 사용할 수도 있습니다.

    ${name:?variable is empty} 

    댓글

    • ” 또는 공백 포함 “은 사실이 아닙니다.
    • 주의하십시오. 현재 셸을 종료합니다. (: $ {subshell?})에 넣는 것이 좋습니다. 또한-stderr에 기록됩니다-아마도 리디렉션을 원할 것입니다. 그리고 가장 중요한 변수가 설정되지 않거나 null이 아닌 경우 변수 ‘의 실제 값으로 평가됩니다. 거기에 명령이 ‘ 있으면 방금 실행 한 것입니다. ‘ :에서 해당 테스트를 실행하는 것이 가장 좋습니다.
    • 쉘을 종료하는 방법입니다. 그리고 u는 이것을 테스트 할 수 있습니다. 먼저 name=aaaa를 정의한 다음이 명령을 실행합니다. echo ${name:?variable is empty} 변수 이름의 값을 인쇄하고 이제이 명령을 실행합니다. echo ${name1:?variable is empty} -sh : name1 : 변수가 비어 있습니다.
    • 예-echo ${name:?variable is empty} $name ‘의 null이 아닌 값으로 평가되거나 셸을 종료합니다. 따라서 같은 이유로 ‘ prompt > $randomvar도하지 마십시오. ${var?}-만약 거기에 ‘ 명령어가 있으면 ‘ 아마 실행될 것입니다. 그리고 당신은 ‘ 그것이 무엇인지 모릅니다. 대화 형 셸은 ‘ 종료 할 필요가 없습니다. 이것이 바로 귀하의 셸이 ‘이없는 이유입니다. 그래도 몇 가지 테스트를보고 싶다면 여기 에 많은 테스트가 있습니다. 이 항목은 ‘ 그다지 길지 않습니다 …

    답변

    게시 한 코드 [[ ! -z $param ]] && echo "I am not zero"는 다음과 같은 경우 I am not zero를 인쇄합니다. param은 설정되지 않았거나 정의되지 않았거나 비어 있습니다 (bash, ksh 및 zsh에서).

    매개 변수에 공백 만 포함 된 경우 인쇄 (공백 제거), POSIXly (더 넓은 범위의 셸용) :

     [ -z "${param#"${param%%[! ]*}"}" ] && echo "empty" 

    설명 :

    • ${param# … } 선행 텍스트를 제거합니다.
    • 그 선행 텍스트는 다음과 같이 지정됩니다. ${param%%[! ]*}
    • 앞의 모든 공백으로 확장 됨 모든 비 공백 문자, 즉 모든 선행 공백.

    전체 확장의 최종 결과는 모든 선행 공백이 제거된다는 것입니다.

    이 확장 된 결과는 길이가 0 인 경우 테스트됩니다.

    • 결과가 비어 있으면 변수가 비어 있거나
    • 앞의 공백을 제거합니다. 비 웠습니다.

    따라서 테스트가 참이면 변수는 이미 비어 있거나 그 안에 공백 만있는 것입니다.


    개념은 더 많은 것으로 확장하기 쉽습니다. 문자 유형. 탭도 포함하려면 대괄호 표현식 안에 명시적인 탭을 배치하세요.

     [ -z "${param#"${param%%[! ]*}"}" ] && echo "empty" 

    또는 제거해야하는 문자가있는 변수를 사용하세요.

     var=$" \t" # in ksh, bash, zsh [ -z "${param#"${param%%[!$var]*}"}" ] && echo "empty" 

    또는 POSIX “문자 클래스 표현식”(공백은 공백과 탭을 의미)을 사용할 수 있습니다.

     [ -z "${param#"${param%%[![:blank:]]*}"}" ] && echo "empty" 

    답변

    변수에 공백 만 있는지 확인하려면 여러 줄 변수 , 시도해보세요 :

    [[ $var = *[$" \t\n"]* ]] 

    또는 xargs를 사용하는 경우 :

    [[ -z $(echo $var | xargs) ]] 

    또는 sed 사용 :

    [[ -z $(sed "/^$/d" <<< $var) ]] 

    답변

    시도해보세요 :

    $ [[ -z \`echo $n\` ]] && echo zero zero 

    답글 남기기

    이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다