문자열에 개행 문자가 있는지 확인하고 있는 경우 이를 제거하는 방법

문자열에 개행 문자가 있는지 확인하고 있는 경우 이를 제거하는 방법

내가 제어할 수 없는 일부 작업의 결과인 문자열이 있습니다. 를 사용하여 이 변수를 인쇄하면 다음과 같은 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

이것이 실제로 a 및 에 의한 것인지 확인하려면 어떻게 해야 합니까 newline? 그렇다면 제거해야 합니까?

답변1

문제는 캐리지 리턴(CR, \r)이 포함되어 있다는 것입니다. 이로 인해 터미널 텍스트 삽입 지점이 인쇄 중인 줄의 시작 부분으로 돌아갑니다. 이것이 바로 예제의 줄 시작 부분에 "hello"가 표시되는 이유입니다. $newVAR이는 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

이것고정시키다사용쉘 매개변수 확장. 위에 사용된 특정 형식은 제공한 패턴을 기반으로 하위 문자열을 바꾸는 데 사용됩니다.${parameter/pattern/string}<-- 이것은 처음 발견된 것만 대체합니다.무늬그리고*parameter라는 변수에 있습니다. 바꾸다모두모드에서는 첫 번째 항목 ///.

답변2

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이와 관련하여 그것이 무엇을 하는지 모른다면 언급할 가치가 있다고 생각했습니다 . 물론, 그것에 대해 배우면서 나는 그것에 대한 유용한 응용 프로그램을 많이 발견했습니다.

답변4

Bash 및 기타 쉘 언어가 편리하지만 때로는 Perl과 같은 실제 스크립트 언어를 사용하는 것이 더 나을 때도 있습니다. Perl은 UNIX 명령뿐만 아니라 다른 언어(예: sed 및 awk)를 호출하는 쉘 스크립트를 매우 쉽게 대체할 수 있습니다. 저는 20년 전에 sed, awk 및 FORTRAN 코드라고 불리는 다양한 UNIX 명령을 호출하는 C-Shell 스크립트를 작성하면서 이 사실을 배웠습니다. 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";
  }

관련 정보