bash 스크립트에서 변수에 줄 바꿈을 추가하는 방법


답변:


73

에서 bash당신은 구문을 사용할 수 있습니다

str=$'Hello World\n===========\n'

작은 따옴표 앞에는 $이스케이프 시퀀스를 문자열에 삽입 할 수있는 새로운 구문이 있습니다.

또한 printf내장은 결과 출력을 변수에 저장할 수 있습니다

printf -v str 'Hello World\n===========\n'

두 솔루션 모두 서브 쉘이 필요하지 않습니다.

다음에서 문자열을 인쇄해야하는 경우 다음 예와 같이 큰 따옴표를 사용해야합니다.

echo "$str"

따옴표없이 문자열을 인쇄하면 줄 바꿈이 공백으로 변환되기 때문입니다.


1
구문이란 무엇입니까 str=$'Hello World\n===========\n'? 변수 대체?
zengr

5
@zengr : ANSI-C quoting 이라고 하며 zsh및 에서 지원됩니다 ksh. 그러나 POSIX 호환이 아닙니다.
mklement0

4
@ mkelement0은 ksh93에서 제공되며 zsh, bash, mksh 및 FreeBSD sh에서도 지원되며 POSIX의 다음 주요 개정판에 포함 되는 내용
Stéphane Chazelas

1
큰 따옴표로 작동하지 않는 것 같습니까? 예를 들어 str=$"My $PET eats:\n$PET food"? 이 접근법 은 큰 따옴표에 적용됩니다
Brad Parks

31

작은 따옴표 (Bourne / POSIX 스타일 쉘) 안에 리터럴 개행을 넣을 수 있습니다.

str='Hello World
===========
'

여러 줄 문자열의 경우 여기 문서 가 종종 편리합니다. 문자열은 명령에 입력으로 공급됩니다.

mycommand <<'EOF'
Hello World
===========
EOF

문자열을 변수에 저장하려면 cat명령 대체에서 명령을 사용하십시오 . 문자열 끝에있는 줄 바꿈 문자는 명령 대체에 의해 제거됩니다. 마지막 줄 바꿈을 유지하려면 끝에 마개를 놓고 나중에 제거하십시오. POSIX 호환 쉘에서는 str=$(cat <<'EOF'); str=${str%a}heredoc을 적절히 쓸 수 있지만 bash는 heredoc이 닫는 괄호 앞에 나타나도록 요구합니다.

str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}

ksh, bash 및 zsh에서 $'…'인용 된 양식을 사용하여 인용 부호 내에서 백 슬래시 이스케이프를 확장 할 수 있습니다 .

str=$'Hello World\n===========\n'

1
GNU bash 4.1.5를 사용하고 있으며 그대로 str=$(cat <<'EOF')작동하지 않습니다. )doc 종료 후 다음 줄에 배치해야 EOF하지만 .. 치환.
Peter.O

@fred 좋은 점, 나는 후행 줄 바꿈에 대해 설명하고 bash에서 작동하는 코드를 보여주었습니다. 나는 그것이 bash의 버그라고 생각하지만 POSIX 사양을 다시 읽었을 때 정직해야하지만 <<가 명령 대체 내부에 있고 heredoc이 없을 때 동작이 지시되는지 확실하지 않습니다.
Gilles

좋은 물건; 변수에서 here-doc을 캡처 할 때 후행 및 선행 \n인스턴스 를 유지 하려면 스토퍼 접근법의 대안으로 bash고려 IFS= read -r -d '' str <<'EOF'...하십시오 (내 답변 참조).
mklement0

8

"에코"를 사용하고 있습니까? "echo -e"를 시도하십시오.

echo -e "Hello World\n===========\n"

2
BTW. echo-n을 지정하지 않으면 마지막 \ n 은 자동으로 추가 되므로 필요하지 않습니다 . 그러나 질문의 ​​주된 강점은 이러한 줄 바꿈을 변수로 만드는 방법입니다.
Peter.O

+1 모든 솔루션 중에서 가장 직접적이고 가장 간단한 솔루션입니다.
Hai Vu

-e는 OS의 X에서 작동하지 않습니다 에코
그렉 M. Krsak에게

2
@GregKrsak :에서가 bash, echo -e 않습니다 OS X에 대한 작업을 - 때문에 그건 echo떠들썩한 파티입니다 내장 (보다는 외부 실행 파일) 그리고 내장 지원을한다 -e. (A 내장, 그것은 작동해야 모든 배쉬가 실행되는 플랫폼, 부수적으로, echo -e작동 kshzsh도). 그러나 OS X 의 외부 echo유틸리티/bin/echo실제로 지원 하지 않습니다-e .
mklement0

3

스크립트에 줄 바꿈이 여러 번 필요한 경우 줄 바꿈이있는 전역 변수를 선언 할 수 있습니다. 그렇게하면 큰 따옴표로 묶은 문자열 (가변 확장)에 사용할 수 있습니다.

NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"

$''서브 쉘 이 필요할까요?
Mat

죄송합니다. 답변을 잘못 읽었습니다.
pihentagy 2016 년

다운 보터에게 설명을 요청할 수 있습니까?
pihentagy

좋은! 이것은 큰 따옴표를 사용하여 변수에 포함될 수 있습니다. 예 :"My dog eats:${NL}dog food"
Brad Parks

3

모든 토론에서 가장 간단한 방법은 다음과 같습니다.

bash$ str="Hello World
==========="
bash$ echo "$str"
Hello World
===========

에코 명령을 사용해야합니다 따옴표 .


3

기존의 훌륭한 답변을 보완하려면 :

당신이 사용하는 경우 bash당신이 선호 읽기 쉽도록 실제 줄 바꿈을 사용하여 , read또 다른 옵션 변수에 여기-문서를 캡처 (여기에 다른 솔루션과 같은) 서브 쉘의 사용을 필요로하지 않습니다.

# Reads a here-doc, trimming leading and trailing whitespace.
# Use `IFS= read ...` to preserve it (the trailing \n, here).
read -r -d '' str <<'EOF'   # Use `IFS= read ...` to preserve the trailing \n
Hello World
===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"
[Hello World
===========]
  • -r그 보장 read(기본적으로는 특별한 백 슬래시를 치료하는 것입니다,하지만이 거의 필요하지 않습니다) 입력을 해석하지 않습니다.

  • -d ''"레코드"구분 기호를 빈 문자열로 설정하여 한 줄이 아닌 전체 입력을 한 번 read에 읽습니다 .

두어 유의 $IFS, 디폴트로 (내부 필드 세퍼레이터) $' \t\n'(공간, 탭, 개행)를 임의의 선행 및 후행 공백이 트리밍 에 할당 된 값에서 $str여기에-문서의 후미 개행을 포함한다.
here-doc의 본문은 시작 구분 기호 ( 여기) 다음 줄 부터 시작 하지만 앞에 새 줄이 포함 'EOF'되지 않습니다 .

일반적으로이 원하는 동작입니다,하지만 당신은 줄 바꿈 후행 것을 원하는 경우, 사용 IFS= read -r -d ''대신의 read -r -d '', 그러나주의 모든 선행 및 후행 공백이 후 유지됩니다.
( 명령 앞에 IFS= 직접 추가 하면 해당 read명령 중에 만 할당이 적용되므로 이전 값을 복원 할 필요가 없습니다.)


here-doc을 사용하면 선택적으로 들여 쓰기사용 하여 가독성을 위해 여러 줄 문자열을 설정할 수 있습니다 .

# Caveat: indentation must be actual *tab* characters - spaces won't work.
read -r -d '' str <<-'EOF' # NOTE: Only works if the indentation uses actual tab (\t) chars.
    Hello World
    ===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.
# Note how the leading tabs were stripped.
$ echo "$str"
[Hello World
===========]

here-doc 구분 기호 ( , here) -사이에 배치 하면 here-doc 본문과 닫는 구분 기호에서 선행 탭 문자가 제거되지만 공백이 아닌 실제 탭 문자 에서만 작동 합니다. 편집기는 탭 키 누르기를 공백으로 변환하므로 추가 작업이 필요합니다.<<'EOF'


-1

당신은 이런 식으로해야합니다 :

STR=$(echo -ne "Hello World\n===========\n")

최신 정보:

프레드가 지적했듯이이 방법으로 후행 "\ n"을 잃게됩니다. 백 슬래시 시퀀스가 ​​확장 된 변수를 지정하려면 다음을 수행하십시오.

STR=$'Hello World\n===========\n\n'

테스트 해보자.

echo "[[$STR]]"

우리에게 지금 :

[[Hello World
===========

]]

$ ''는 $ ""과 다릅니다. 두 번째는 현재 로케일에 따라 번역을 수행합니다. 자세한 내용은의 QUOTING 섹션을 참조하십시오 man bash.


-2
#!/bin/bash

result=""

foo="FOO"
bar="BAR"

result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'

echo "$result"
printf '%s' "$result"

산출:

FOO
BAR

FOO
BAR

1
왜 간단하지 result+=$foo$'\n'않습니까? $(printf %s "$foo")후행 줄 바꿈 문자가있는 $foo경우 자릅니다 .
Stéphane Chazelas

코드에 대한 설명이 없으면 그렇지 않습니다.
뭔가 뭔가
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.