배쉬 연속 라인


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.