문자열에 개행 문자가 있다고 주장하고 제거하는 경우 제거하는 방법


9

제어 할 수없는 일부 작업의 결과 인 문자열이 있습니다. 를 사용 하여이 변수를 인쇄하면 다음과 같은 결과 echo가 나타납니다.

echo $myvar
hello

그러나 내가 할 때

if [ $myvar = "hello" ]; then
    echo they are equal
else
    echo they are not equal
fi

나는 항상 그들이 같지 않다는 것을 얻는다. 나는 이것이 newline성격 때문이라고 생각합니다 .

문자열도 이상하게 동작합니다. 내가 할 때 :

newVAR="this is my var twice: "$myvar$myvar
echo $newVAR

나는 얻다:

hellois my var twice: hello

이것이 실제로 발생한 것인지 어떻게 확인 newline하고, 그렇다면 제거 할 수 있습니까?


1
Bash에서는 printf '%q\n' "$string"모든 문자열의 이스케이프 버전을 얻을 수 있습니다 . 예를 들면 다음과 같습니다 printf '%q\n' 'foo\n'.-> foo\\n; printf '%q\n' $'foo\n'->$'foo\n'
l0b0

1
변수의 확장을 인용하지 않습니다. 그들이 뒤에 공백이 있다면, 당신은 그것을 볼 수 없습니다 echo $foo. 수행 echo "$foo"하는 대신.
Peter Cordes

답변:


9

문제는 캐리지 리턴 (CR, \r)이 내장되어 있다는 것 입니다. 이로 인해 터미널 텍스트 삽입 점이 인쇄중인 줄의 시작 부분으로 되돌아갑니다. 당신이 $newVAR예제 에서 줄의 시작 부분에 'hello'가 나타나는 이유입니다 - sed -n l인쇄 할 수없는 문자 (및 줄 끝)의 읽을 수있는보기를 표시합니다.

var=ab$'\r'c ; echo "$var";  printf %s "$var" | sed -n l
# output:
cb
ab\rc$

간단한 bash 조건 확인으로 테스트 할 수 있습니다.

[[ $var == *$'\r'* ]] && echo yes || echo no
# output:
yes

다음을 통해 테스트하고 수정하여 테스트와 수정을 한 단계로 결합 할 수 있습니다 \r.

fix="${var//$'\r'/}"; echo "$var"; echo "$fix"
# output:
cb
abc

수정Shell Parameter Expansion을 사용합니다 . : 위에서 사용 된 특정 형태는 proovided 패턴을 기반으로 문자열 교체입니다 ${parameter/pattern/string}-이 대체합니다만을 먼저 발견의 < 패턴 을 가진 문자열 * 매개 변수라는 이름의 변수를. 교체하려면 모든 패턴을, 당신은 단지 첫 번째 변경해야 /하는가 //.


마지막 코드를 설명해 주시겠습니까? fix="....라인?
farid99

@ farid99 : 설명에 답변이 추가되었습니다. 참고 자체 fix가 될 수도 있고 var종종 수정 된 값을 다시 할당 할 필요없이 매개 변수 확장을 그대로 사용할 수도 있습니다.
Peter.O

5

bash에서 \r와 같이 나타낼 수 있습니다 $'\r'.

if [ "$myvar" = "hello"$'\r' ]; then
    echo they are equal
else
    echo they are not equal
fi

또는 마지막 \r을 잘라 myvar:

if [ "${myvar%$'\r'*}" = "hello" ]; then
    echo they are equal
else
    echo they are not equal
fi

3

흥미롭게도 많은 쉘에서 getopts이와 같은 작업의 후보가 될 가능성이 큽니다. 이것은 처음에는 반 직관적으로 보일지 모르지만, getopts기본 함수가 일련의 동일한 일련의 문자열에서 볼 수있는 것처럼 지정된 단일 문자 명령 행 옵션을 인식하고 해석 하는 것을 고려한다면 , 더 의미가 있습니다.

bash쉘 에서 설명하려면 :

x=$(printf '\n\r%010s\t' hello)
OPTIND=1
while  getopts : na "-$x"
do     printf %q\\n "$OPTARG"
done

$'\n'
$'\r'
\
\
\
\
\
h
e
l
l
o
$'\t'

이런 식으로 getopts해체를 일종의 쉘 자동 조종 장치로 취급하는 것이 때때로 편리 할 수 있습니다. 그렇게 할 때, 원하지 않는 바이트를 사용하여 검사 case하거나 바이트 1에서 문자열 백업을 [테스트 ]하고 빌드 할 수 있습니다.

OPTIND=1 y=$(printf \\n\\r) z=
while  getopts : na "-$x"
do     case $OPTARG in ([!$y])
            z=$z$OPTARG
       esac
done
printf %q\\n "$z"

$'     hello\t'

이 간단한 예제 사례와 이미 언급 한 다른 매개 변수 확장을 지원하는 셸을 사용하면 확장이 아마도 더 나은 서비스를 제공 할 것입니다. 그러나이 getopts점에서 그 기능을 알지 못하는 경우를 대비하여 언급 할 가치가 있다고 생각 했습니다. 확실히 내가 그것을 알았을 때 어쨌든 많은 유용한 응용 프로그램을 찾았습니다.


0

Bash와 다른 쉘 언어는 편리하지만 때로는 Perl과 같은 진정한 스크립팅 언어를 사용하는 것이 좋습니다. Perl은 sed 및 awk와 같은 다른 언어를 호출하는 쉘 스크립트와 UNIX 명령을 매우 쉽게 대체 할 수 있습니다. FORTRAN 코드를 호출하기 전에 20 년 전 C-Shell 스크립트를 작성할 때 sed, awk 및 다양한 UNIX 명령을 호출 할 때 배웠습니다. Perl에서는 다음을 수행합니다.

chomp($myvar);   # removes the newline char

if("$myvar" eq "hello")   # string comparison
  {
  print "they are equal\n";
  }
else
  {
  print "they are not equal\n";
  }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.