echo를 사용할 때 새 줄을 추가하는 방법


42

다음 명령이 생성 된 파일에 줄 바꿈을 삽입하지 않는 이유와 해결 방법은 무엇입니까?

$ echo "Line 1\r\nLine2" >> readme.txt

$ cat readme.txt 
Line 1\r\nLine2

6
인가 echo필수? 사용할 수 있습니다 printf.
Archemar

printf에 대해 몰랐습니다. printf와 함께 작동합니다 : P ... 그렇다면 echo와 함께 작동하지 않는 것은 무엇입니까?
Saeid Yazdani

IS는 \r출력에 포함 또는 그것의 일부 CRLF줄 바꿈?
cuonglm

9
서로 echo호환되지 않는 명령 구현에는 여러 가지가 있습니다 . 따라서보다 많은 표준 도구를 사용하는 것이 좋습니다 printf. 문제에 대한 확장 된 개요는 unix.stackexchange.com/questions/65803/… 을 참조하십시오 .
jimmij

답변:


38

echo


echo단일 유닉스 사양을 엄격하게 준수 하는 구현은 다음과 같은 경우 줄 바꿈을 추가합니다.

echo 'line1\nline2'

그러나 그것은 믿을만한 행동이 아닙니다. 사실, 정말이 없는 당신이 기대할 수있는 표준 동작 echo.

OPERANDS

string

표준 출력에 쓸 문자열입니다. 첫 번째 피연산자가 -n이거나 피연산자 중 하나에 < \backslash> 문자가 포함 된 경우 결과는 구현 정의됩니다 .

XSI 준수 '의 첫 번째 피연산자 인 경우 시스템 -n, 그것은 문자열로 취급되어야 하지 옵션 . 다음 문자 시퀀스는 XSI 준수 시스템에서 모든 인수 내에서 인식되어야합니다.

\a- <alert>를 작성하십시오 .

\b- <backspace>를 작성하십시오 .

\c- 그렇지 않으면 출력에서 ​​최종 인수 뒤에 오는 <newline> 을 억제하십시오 . \c인수에서 다음에 나오는 모든 문자 는 무시됩니다.

\f- <form-feed>를 작성하십시오 .

\n- <newline>을 작성하십시오 .

\r- <캐리지 리턴>을 작성하십시오 .

\t- <tab>을 작성 하십시오 .

\v- <vertical-tab>을 작성 하십시오 .

\\- <backslash> 문자를 작성하십시오 .

\0num-0, 1, 2 또는 3 자리 8 진수 인 8 비트 값을 씁니다 num.

따라서 개행을 작성하는 방법을 알 수있는 일반적인 방법은 없습니다 echo. 단지 그렇게하는 것에 만 의존 할 수 있습니다 echo.

bash쉘은 일반적으로 않습니다 하지 규격을 준수하고, 처리 -n불확실 심지어 다른 옵션을하지만. 넌 할 수있어:

shopt -s xpg_echo
echo hey\\nthere

hey
there

그리고 빌드 타임 옵션으로 빌드 된 경우 에도 필요 하지 않습니다bash ...

--enable-xpg-echo-default

만들기 기능 echo내장이 필요없이 기본적으로 백 슬래시 이스케이프 문자를 확장 -e옵션을 선택합니다. xpg_echo쉘 옵션 의 기본값을로 설정하면 onBash echo가 Single Unix Specification 버전 3에 지정된 버전과 비슷하게 동작합니다 . 인식 하는 이스케이프 시퀀스에 대한 설명은 Bash Builtins를 참조하십시오 echo.


printf


반면에 printf의 행동은 비교에서 꽤 길다.

이론적 해석

printf유틸리티는 이전에 제공되었던 기능을 제공하기 위해 추가되었습니다 echo. 그러나 현존하는 다양한 버전의 비교할 수없는 차이 로 인해 echo버전에는 특별한 기능이 거의 없으므로이 새로운 printf유틸리티는 Ninth Edition 시스템의 기능을 기반으로합니다.

확장 설명 섹션 printf()XBD 파일 형식 표기법 의 파일 형식 표기법으로 설명되어 있지만 ISO C 표준 의 기능 과 거의 정확하게 일치합니다 .

인수를 설명하는 형식 문자열을 처리합니다. 여러 가지가 될 수 있지만 문자열의 경우 %b문자열이나 리터럴 트렁 %s입니다. 댄 다른 %f첫 번째 인수에 ormats, 그것은 같은 대부분의 동작 %bYTE 문자열 인수를가 처리하지 않는다는 점을 제외 \c탈출.

printf ^%b%s$ '\n' '\n' '\t' '\t'

^
\n$^    \t$

printf보다 낫 echo습니까?를 참조하십시오 . 이상.


echo() printf


다음 echo과 같은 표준을 자체적으로 작성할 수 있습니다 .

echo(){
    printf '%b ' "$@\n\c"
}

... 언제나 항상 올바른 일을 자동으로 수행해야합니다.

실제로, 아니오 ... \n마지막 인수가 홀수 <backslashes>로 끝나면 인수의 끝에 리터럴 을 인쇄합니다 .

그러나 이것은하지 않습니다 :

echo()
    case    ${IFS- } in
    (\ *)   printf  %b\\n "$*";;
    (*)     IFS=\ $IFS
            printf  %b\\n "$*"
            IFS=${IFS#?}
    esac

기본적 으로 사용 하는 shopt -s xpg_echo옵션은 +1입니다 . echo-e
Vignesh Raja

이 솔루션은 없이는 작동하지 않습니다 -e. 나는 아무도 눈치 없음을 놀라게하고 그 아마도 @HaydeSchiff 제외
ha9u63ar

@ ha9u63ar-uhh ... 이거 읽었 어?
mikeserv

27

-e 플래그를 에코하여 "\ r \ n"과 같이 이스케이프 된 문자를 구문 분석하십시오.

echo -e "Line 1\r\nLine2" >> readme.txt

이스케이프 시퀀스를 작동시키는 좋은 간단한 "-e"옵션- echo신뢰할 수없고 표준과 다른 표준을 따르지 않는 다른 답변에 대해 말합니다 printf.
Edward

1
스크립트에 tr -d "\n"명령 과 같이 리터럴 \ r \ n이 포함되어 있지 않은지 확인하십시오 .
누 메논

8

필자가 사용한 모든 버전의 bash에서 문자열이 충분히 인용 된 경우 리터럴 개행을 대화 형 또는 스크립트로 문자열에 삽입 할 수 있습니다.

대화식으로 :

$ echo "Line one
> Line two"
Line one
Line two
$

스크립트에서 :

echo "Line one
Line two"

4
echo -e "Line 1\r\nLine2" >> readme.txt

추가 사용 가능성 :

man echo

2

사람들은 이미 적절하게 답변했지만 에코가 이외의 옵션을 허용하는 세계는 수락하지 않습니다 -n.

nl='
'
echo Line 1"$nl"Line 2"$nl"Line 3

1

메시지의 일부가 아닌 문자가있는 경우 sed를 통해 파이프 할 수 있습니다

$ echo "Time on the next line:@$(date +"%Y-%m-%dT%T%z")" | sed -e's/@/\n/g'
Time on the next line:
2016-03-25T10:12:39-0500
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.