Bash에서 여러 줄 문자열을 출력하는 방법은 무엇입니까?


250

다중 에코 호출을 사용하지 않고 Bash에서 다중 행 문자열을 출력하는 방법은 다음과 같습니다.

echo "usage: up [--level <n>| -n <levels>][--help][--version]"
echo 
echo "Report bugs to: "
echo "up home page: "

Bash 내장 만 사용 하여이 작업을 수행 할 수있는 휴대용 방법을 찾고 있습니다.


4
잘못된 호출에 대한 응답으로 사용 메시지를 출력하는 경우 일반적으로 다음 메시지를 사용하여 해당 메시지를 표준 출력 대신 표준 오류로 보냅니다.echo >&2 ...
— Mark Reed

2
@MarkReed 사용법 메시지는 다음을 입력하여 출력됩니다 --help(표준 출력으로 이동해야 함).
— helpermethod

다른 사람들을 위해, "여기 문서들"에 대한 더 많은 정보가 있습니다 : tldp.org/LDP/abs/html/here-docs.html
— Jeffrey Martinez

printfGordon Davidson 의 기반 솔루션을 확인하십시오 . echo또는 cat접근 방식 의 그림자에 있지만 , 그것은 훨씬 덜 혼란스러운 것 같습니다. 분명히 'printf'문법은 약간의 학습 곡선을 나타내지 만 다른 단점 (? 호환성, 성능? ...)을 원합니다.
— mjv

답변:


296

여기서는 종종 이러한 목적으로 문서가 사용됩니다.

cat << EOF
usage: up [--level <n>| -n <levels>][--help][--version]

Report bugs to: 
up home page:
EOF

모든 Bash 버전을 포함하여 모든 Bourne 파생 쉘에서 지원됩니다.


4
응-하지만 cat내장되어 있지 않습니다.
— Mark Reed

8
@MarkReed : 사실이지만 항상 사용 가능합니다 (특별한 상황에서는 제외).
— 추후 공지가있을 때까지 일시 중지되었습니다.

6
+1 Thx. 여러 read -d '' help <<- EOF ...줄 문자열을 변수로 읽은 다음 결과를 에코했습니다.
— helpermethod 2016 년

3
HEREDOC을 변수에 저장할 수 있습니까?
— chovy

177

또는 당신은 이것을 할 수 있습니다 :

echo "usage: up [--level <n>| -n <levels>][--help][--version]

Report bugs to: 
up home page: "

1
@OliverWeiler : Dash 및 Heirloom Bourne Shell 과 같은 Bourne 쉘에서도 작동 합니다.
— 추후 공지가있을 때까지 일시 중지되었습니다.

6
1) 문자열을 파일 왼쪽 끝까지 들여 쓰기하거나 2) 나머지 코드와 일치하도록 들여 쓰기를 유지해야하지만 함수 로이 기능을 필요로하는 경우 좋지 않습니다. 들여 쓰기
— sg

43

이 페이지의 통찰력있는 답변에서 영감을 얻어 가장 단순하고 유연한 방법을 고려한 혼합 접근법을 만들었습니다. 어떻게 생각해?

먼저 변수에 사용법을 정의하여 다른 컨텍스트에서 재사용 할 수 있습니다. 형식은 제어 문자를 추가 할 필요없이 매우 단순하고 거의 WYSIWYG입니다. 이것은 나에게 합리적으로 휴대용 것 같습니다 (MacOS 및 Ubuntu에서 실행했습니다)

__usage="
Usage: $(basename $0) [OPTIONS]

Options:
  -l, --level <n>              Something something something level
  -n, --nnnnn <levels>         Something something something n
  -h, --help                   Something something something help
  -v, --version                Something something something version
"

그런 다음 간단히 사용할 수 있습니다

echo "$__usage"

또는 매개 변수를 구문 분석 할 때 하나의 라이너로 에코 할 수 있습니다.

levelN=${2:?"--level: n is required!""${__usage}"}

4
이것은 위의 대답이 수정되지 않은 스크립트에서 나를 위해 일했습니다.
— David Welch

3
이것은 텍스트에서 찾기 어렵고 스크립트에서 문자열과 출력을 크게 다르게 확장하기 어려운 \ t 및 \ n과 같은 많은 문자를 포함하는 것보다 훨씬 더 깨끗합니다.
— sg

1
어떤 이유로 그것은 나를 위해 같은 줄에 모든 것을 인쇄합니다 : /
— Nicolas de Fontenay

2
@Nicolas : 큰 따옴표를 echo "$__usage"사용해야했습니다. echo $__usage작동하지 않았다.
— 마리오

24

-e옵션을 사용 \n하면 문자열에서 줄 바꿈 문자를 인쇄 할 수 있습니다 .

샘플 (하지만 좋은지 아닌지 확실하지 않음)

재밌는 점은 -e옵션이 여전히 사용 가능하지만 MacOS 매뉴얼 페이지에 설명되어 있지 않다는 것입니다 . 리눅스 매뉴얼 페이지에 설명되어있다 .


6
해당 매뉴얼 페이지는 시스템 제공 echo명령을 위한 것이며 /bin/echo, Mac OS에서는 -e옵션 이 없습니다 . 해당 시스템에서 bash를 사용하면 내장 echo명령이 대신합니다. /bin/echo whatever동작의 차이점 을 명시 적으로 입력 하고 관찰하면 이를 확인할 수 있습니다 . 내장 문서를 보려면을 입력하십시오 help echo.
— Mark Reed

1
/bin/echo종종 OS마다 다르고 Bash의 내장과 다릅니다 echo.
— 추후 공지가있을 때까지 일시 중지되었습니다.

@MarkReed : 나중에 다시 시도하지만 정보를 주셔서 감사합니다. +1. 나는 많은 좋은 토론이 진행되고 있기 때문에 여기에 대답을 남길 것입니다.
— nhahtdh 2016 년

7
echo -e예를 들어, 일부 echo 구현은 "-e"를 출력의 일부로 인쇄합니다. 이식성을 원하면 printf를 대신 사용하십시오. 예를 들어, OS X 10.7.4의 / bin / echo가이를 수행합니다. IIRC bash 내장 에코도 10.5.0에서 이상했지만 더 이상 세부 사항을 기억하지 못합니다.
— Gordon Davisson

2
echo -e전에 저를 물었습니다 ... 확실히 printf또는 catheredoc와 함께 사용하십시오 . <<-스크립트의 가독성을 위해 당신이 출력에 들여 쓰기를 선도 제거 할 수 있기 때문에 문서가 특히 좋은 여기에의 변형,하지만 들여 쓰기
— zbeekman

22

printf의견에서 권장 했으므로 사용법에 대한 몇 가지 예를 제시해야합니다 (사용 메시지를 인쇄하더라도 Dennis 또는 Chris의 답변을 사용할 가능성이 큽니다). printf보다 사용하기가 조금 더 복잡합니다 echo. 첫 번째 인수는 형식 문자열이며 이스케이프 (예 :) \n는 항상 해석됩니다. 또한 %추가 인수가 포함되는 위치 및 방법을 제어하는 형식 지시문을 포함 할 수 있습니다 . 사용법 메시지에 사용하는 두 가지 방법이 있습니다.

먼저 전체 메시지를 형식 문자열에 포함시킬 수 있습니다.

printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: \nup home page: \n"

와 달리 echo최종 개행 문자를 명시 적으로 포함해야합니다. 또한 메시지에 %문자 가 포함되어 있으면 로 작성해야 %%합니다. 버그 리포트와 홈페이지 주소를 포함하고 싶을 경우, 자연스럽게 추가 할 수 있습니다.

printf "usage: up [--level <n>| -n <levels>][--help][--version]\n\nReport bugs to: %s\nup home page: %s\n" "$bugreport" "$homepage"

둘째, 형식 문자열을 사용하여 각 추가 인수를 별도의 줄에 인쇄 할 수 있습니다.

printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: " "up home page: "

이 옵션을 사용하면 버그 리포트 및 홈페이지 주소를 추가하는 것이 매우 분명합니다.

printf "%s\n" "usage: up [--level <n>| -n <levels>][--help][--version]" "" "Report bugs to: $bugreport" "up home page: $homepage"

9

또한 들여 쓰기 된 소스 코드를 사용하면 <<-(후행 대시와 함께) 선행 탭을 무시할 수 있지만 선행 공백은 무시할 수 있습니다. 예를 들면 다음과 같습니다.

if [ some test ]; then
    cat <<- xx
        line1
        line2
xx
fi

선행 공백없이 들여 쓰기 된 텍스트를 출력합니다.

line1
line2

그것은 나를 위해 작동하지 않았다. 어떤 쉘을 사용하고 있습니까?
— four43

우분투의 bash 4.4.19에서는 작동하지 않았습니다.
— line1

1
@ four43, 네 말이 맞아 선행 공백을 제거하기 위해 작동하지 않습니다. 그러나 선행 탭을 제거합니다. 그래서 탭과 공백에서 공백이 아닌 탭으로 답을 수정했습니다. 실수해서 죄송합니다. 매뉴얼을 확인했는데 탭이 제거되었다는 것을 분명히 나타냅니다. 관심을 가져 주셔서 감사합니다.
— 타원형보기

0

@jorge의 솔루션을 사용하고 모든 줄이 같은 줄에 있으면 변수를 따옴표로 묶어야합니다.

echo $__usage

한 줄에 모든 것을 인쇄하지만

echo "$__usage"

줄 바꿈을 유지합니다.


이것은 실제로 나를 위해 일한 솔루션입니다. Printf는 많은 작업을 수행하며 여러 줄 XML을 사용하면 내용을 완전히 엉망으로 만들기 때문에 많은 탈출이 필요합니다. 나는 foo = cat <<EOF .... EOF&& echo "$ foo"를 할당합니다
— Jilles van Gurp
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.