배쉬 연속 라인


158

bash 연속 줄을 어떻게 사용합니까?

나는 당신이 이것을 할 수 있음을 알고 있습니다 :

echo "continuation \
lines"
>continuation lines

그러나 들여 쓰기 코드가 있으면 잘 작동하지 않습니다.

    echo "continuation \
    lines"
>continuation     lines

5
Google의 Bash Shell 스타일 가이드 는 " 80 자보다 긴 문자열을 작성해야하는 경우"에 대한 "여기"문서 를 권장 합니다. @tripleee의 답변을 참조하십시오 .
— Trevor Boyd Smith

google.github.io/styleguide/…- 이것은 새 문서의 직접 링크입니다
— jcollum

답변:


161

이것은 당신이 원하는 것입니다

$       echo "continuation"\
>       "lines"
continuation lines

이것이 반향 할 두 개의 인수를 작성하고 하나만 원하면 문자열 연결을 살펴 보겠습니다. bash에서 두 개의 문자열을 나란히 배치하면 다음과 같이 연결됩니다.

$ echo "continuation""lines"
continuationlines

따라서 들여 쓰기 가 없는 연속 선 은 문자열을 분리하는 한 가지 방법입니다.

$ echo "continuation"\
> "lines"
continuationlines

그러나 들여 쓰기가 사용될 때 :

$       echo "continuation"\
>       "lines"
continuation lines

더 이상 연결이 아니므로 두 개의 인수를 얻게됩니다.

들여 쓰기는하지만 줄을 가로 지르는 단일 문자열을 원한다면 그 줄을 모두 없애고 변수를 사용하는 것이 좋습니다.

$ a="continuation"
$ b="lines"
$ echo $a$b
continuationlines

이를 통해 추가 변수를 희생시키면서 코드를 깔끔하게 들여 쓸 수 있습니다. 변수를 로컬로 만들면 너무 나쁘지 않아야합니다.


1
도움을 주셔서 감사하지만 공백을 제거하는 동안 이제는 별도의 매개 변수 (Bash는 두 번째 줄의 공백을 매개 변수 구분 기호로 해석 함)이며 echo 명령으로 인해 올바르게 인쇄됩니다.

1
아, 하나의 (bash) 문자열이 줄에 걸쳐 있기를 원합니다! 나는 지금 본다.
— Ray Toal

4
하나의 변수가있는 솔루션 :s="string no. 1" s+="string no. 2" s+=" string no. 3" echo "$s"
— Johnny Thunderman

30

여기서 <<-HERE터미네이터 가있는 문서 는 들여 쓰기 된 여러 줄 텍스트 문자열에 적합합니다. 여기 문서에서 선행 탭을 제거합니다. (라인 종결자는 여전히 남아 있습니다.)

cat <<-____HERE
    continuation
    lines
____HERE

참조 http://ss64.com/bash/syntax-here.html

공백이 아닌 일부를 보존 해야하는 경우 다음과 같은 것을 사용할 수 있습니다

sed 's/^  //' <<____HERE
    This has four leading spaces.
    Two of them will be removed by sed.
____HERE

또는 줄 tr바꿈을 제거 하는 데 사용할 수 있습니다 .

tr -d '\012' <<-____
    continuation
     lines
____

두 번째 줄에는 탭과 공백이 있습니다. 여기에서 종료하기 전에 대시 연산자로 탭이 제거되지만 공백은 유지됩니다.

여러 줄에 걸쳐 긴 복잡한 문자열을 줄이려면 printf다음을 좋아합니다 .

printf '%s' \
    "This will all be printed on a " \
    "single line (because the format string " \
    "doesn't specify any newline)"

그것은 또한 당신이 예에서와 같이, 여기에 문서를 사용하면 호스트 언어의 구문을 못하게 다른 언어에있는 쉘 스크립트의 삽입 사소 조각 원하는 상황에서 잘 작동 Makefile하거나 Dockerfile.

printf '%s\n' >./myscript \
    '#!/bin/sh` \
    "echo \"G'day, World\"" \
    'date +%F\ %T' && \
chmod a+x ./myscript && \
./myscript

나를 위해 작동하지 않습니다. 우분투 16.04. 예상되는 한 줄 대신 두 줄을 얻습니다.
— Penghe Geng

@PengheGeng 실제로, 이것은 라인을 연결하는 것이 아니라 들여 쓰기를 없애는 문제를 해결합니다. 줄 끝에서 줄 바꿈을 백 슬래시하여 두 줄을 함께 연결할 수 있습니다.
— tripleee

(그러나 printf이제 첫 번째 예도 참조하십시오 .)
— tripleee

12

bash 배열을 사용할 수 있습니다

$ str_array=("continuation"
             "lines")

그때

$ echo "${str_array[*]}"
continuation lines

(bash 매뉴얼 이후) 다음과 같은 추가 공간이 있습니다.

단어가 큰 따옴표로 묶인 경우 ${name[*]}각 배열 구성원의 값을 IFS 변수의 첫 문자로 구분하여 단일 단어로 확장합니다.

IFS=''여분의 공간을 없애기 위해 설정

$ IFS=''
$ echo "${str_array[*]}"
continuationlines

4

Bash의 연결 기능을 사용하는 특정 시나리오가 적합 할 수 있습니다.

예:

temp='this string is very long '
temp+='so I will separate it onto multiple lines'
echo $temp
this string is very long so I will separate it onto multiple lines

Bash Man 페이지의 PARAMETERS 섹션에서 :

이름 = [값] ...

... 대 입문이 쉘 변수 또는 배열 인덱스에 값을 할당하는 컨텍스트에서 + = 연산자를 사용하여 변수의 이전 값을 추가하거나 추가 할 수 있습니다. 정수 속성이 설정된 변수에 + =를 적용하면 값이 산술 연산 식으로 평가되고 변수의 현재 값에 추가되어 평가됩니다. 복합 할당을 사용하여 배열 변수에 + =를 적용하면 (아래 배열 참조) 변수 값이 설정되지 않고 (=를 사용할 때와 같이) 배열의 최대 색인보다 하나 더 큰 값에서 시작하여 새 값이 배열에 추가됩니다. (인덱스 배열의 경우) 또는 연관 배열에서 추가 키-값 쌍으로 추가되었습니다. 문자열 값 변수에 적용되면 값이 확장되어 변수 값에 추가됩니다.


이 페이지에서 가장 좋은 조언 일 것입니다. HEREDOC을 사용하고 <CR>에 대한 변환으로 파이프를 연결하는 것은 직관적이지 않으며 실제로 문자열에 개별적으로 줄 구분 기호를 배치해야하는 경우 실패합니다.
— ingyhere

2

명령 인수의 일부로 긴 메시지를 보내야하는 상황이 발생하여 줄 길이 제한을 준수해야했습니다. 명령은 다음과 같습니다.

somecommand --message="I am a long message" args

내가 이것을 해결하는 방법은 메시지를 here 문서 (예 : @tripleee 제안)로 옮기는 것입니다. 그러나 here 문서는 stdin이되므로 다시 읽어야하므로 아래 접근 방식을 사용했습니다.

message=$(
    tr "\n" " " <<- END
        This is a
        long message
END
)
somecommand --message="$message" args

$message추가 공백이나 줄 바꿈없이 문자열 상수로 정확하게 사용할 수있는 이점이 있습니다.

위의 실제 메시지 줄 앞에는 tab문자 가 붙어 있으며 여기에 문서 자체가 제거되어 있습니다 (의 사용으로 인해 <<-). 끝에 줄 바꿈이 dd있으며 공백으로 바뀝니다 .

줄 바꿈을 제거하지 않으면 "$message"확장 될 때 그대로 줄 바꿈됩니다 . 경우에 따라 큰 따옴표를 제거하여 해결 방법을 사용할 수 $message있지만 메시지가 더 이상 단일 인수가 아닙니다.


2

줄 연속은 또한 현명한 구문 사용을 통해 달성 될 수 있습니다.

의 경우 echo:

# echo '-n' flag prevents trailing <CR> 
echo -n "This is my one-line statement" ;
echo -n " that I would like to make."
This is my one-line statement that I would like to make.

vars의 경우 :

outp="This is my one-line statement" ; 
outp+=" that I would like to make." ; 
echo -n "${outp}"
This is my one-line statement that I would like to make.

vars의 경우 또 다른 접근법 :

outp="This is my one-line statement" ; 
outp="${outp} that I would like to make." ; 
echo -n "${outp}"
This is my one-line statement that I would like to make.

짜잔!


1

다음과 같이 들여 쓰기 내에서 필요에 따라 줄 바꿈 (백 슬래시를 사용하지 않고)으로 간단히 구분하고 새 줄을 제거 할 수 있습니다.

예:

echo "continuation
of 
lines" | tr '\n' ' '

또는 변수 정의 인 경우 개행은 자동으로 공백으로 변환됩니다. 따라서 해당되는 경우에만 추가 공간을 제거하십시오.

x="continuation
of multiple
lines"
y="red|blue|
green|yellow"

echo $x # This will do as the converted space actually is meaningful
echo $y | tr -d ' ' # Stripping of space may be preferable in this case

1

이것은 사용자가 요구 한 것이 아니지만 여러 줄에 걸쳐있는 긴 문자열을 만드는 또 다른 방법은 다음과 같이 점증 적으로 작성하는 것입니다.

$ greeting="Hello"
$ greeting="$greeting, World"
$ echo $greeting
Hello, World

분명히이 경우 한 번에 빌드하는 것이 더 간단했지만이 스타일은 더 긴 문자열을 다룰 때 매우 가볍고 이해할 수 있습니다.


0

그러나 들여 쓰기 코드가 있으면 잘 작동하지 않습니다.

    echo "continuation \
    lines"
>continuation     lines

작은 따옴표로 묶고 문자열을 연결하십시오.

    echo 'continuation' \
    'lines'
>continuation lines

참고 : 연결에는 공백이 포함됩니다.


2
echo 및 string 인수와 함께 작동하지만 변수 할당과 같은 다른 것에서는 작동하지 않습니다. 변수에 관한 질문은 아니지만 echo를 사용하는 것은 단지 예일뿐입니다. 대신에 echo 당신이 있다면 x=, 당신은 오류를 얻을 것 : lines: command not found.
— LS

0

어떤 종류의 위험을 수용하고 데이터를 얼마나 잘 알고 신뢰하는지에 따라 단순한 변수 보간을 사용할 수 있습니다.

$: x="
    this
    is
       variably indented
    stuff
   "
$: echo "$x" # preserves the newlines and spacing

    this
    is
       variably indented
    stuff

$: echo $x # no quotes, stacks it "neatly" with minimal spacing
this is variably indented stuff

-2

이것은 실제로 귀하의 질문에 대답하지는 않지만 어쨌든 유용 할 수 있습니다.

첫 번째 명령은 두 번째 명령에 의해 표시되는 스크립트를 만듭니다.

세 번째 명령은 해당 스크립트를 실행 가능하게 만듭니다.

네 번째 명령은 사용 예를 제공합니다.

john@malkovich:~/tmp/so$ echo $'#!/usr/bin/env python\nimport textwrap, sys\n\ndef bash_dedent(text):\n    """Dedent all but the first line in the passed `text`."""\n    try:\n        first, rest = text.split("\\n", 1)\n        return "\\n".join([first, textwrap.dedent(rest)])\n    except ValueError:\n        return text  # single-line string\n\nprint bash_dedent(sys.argv[1])'  > bash_dedent
john@malkovich:~/tmp/so$ cat bash_dedent 
#!/usr/bin/env python
import textwrap, sys

def bash_dedent(text):
    """Dedent all but the first line in the passed `text`."""
    try:
        first, rest = text.split("\n", 1)
        return "\n".join([first, textwrap.dedent(rest)])
    except ValueError:
        return text  # single-line string

print bash_dedent(sys.argv[1])
john@malkovich:~/tmp/so$ chmod a+x bash_dedent
john@malkovich:~/tmp/so$ echo "$(./bash_dedent "first line
>     second line
>     third line")"
first line
second line
third line

이 스크립트를 실제로 사용하려면 실행 가능한 스크립트를 이동 ~/bin하여 경로 에 있도록하는 것이 더 좋습니다.

textwrap.dedent작동 방식 에 대한 자세한 내용은 파이썬 참조를 확인하십시오 .

사용법 $'...'이나 "$(...)"혼란 스러우면 다른 질문 (구문 당 하나)이 없는지 물어보십시오. 다른 사람들이 링크 된 참조를 갖도록 찾거나 묻는 질문에 대한 링크를 제공하는 것이 좋습니다.


6
OP는 기본 bash 구문에 대한 조언을 요청했으며 OO 패러다임, 탁월한 흐름 제어 및 가져 오기를 사용하는 Python 함수 정의를 제공했습니다. 또한 실행 파일을 문자열 보간의 일부로 호출했습니다. 이런 종류의 질문을하는 사람은 아직 배쉬에서 보지 못했을 것입니다.
— Parthian Shot
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.