programing

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

closeapi 2023. 5. 31. 15:57
반응형

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

긴 문자열 상수를 여러 줄로 분할하려면 어떻게 해야 합니까?

저는 당신이 이것을 할 수 있다는 것을 알고 있습니다.

echo "continuation \
lines"
>continuation lines

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

    echo "continuation \
    lines"
>continuation     lines

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

$       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

이렇게 하면 추가 변수를 사용하지 않고 코드를 완전히 들여쓸 수 있습니다.변수를 로컬로 만들면 크게 나쁘지 않을 것입니다.

다음 문서는 다음과 같습니다.<<-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)"

에서 여기수 다른 셸하지 않은 에서도 잘 합니다. 를 들어 또한 호 트 언 스 수 다 없 셸 않 부 중 스 포 컨 는 트 에 서 작 잘 동 합 니 다 도 스 텍 려 하 함 을 분 은 의지트하어 요 언의문크립로는어른용서구기사할이 여 문를▁a▁it 또 , ▁document▁script▁language한▁as▁in▁wellMakefile또는Dockerfile.

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

bash 어레이를 사용할 수 있습니다.

$ str_array=("continuation"
             "lines")

그리고나서

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

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

이중따옴표로 만약그단이인다면된용중가어,▁if면,${name[*]}의 첫 됩니다.

설정 ㅠㅠㅠIFS=''의 공간을

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

특정 시나리오에서는 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 섹션에서 다음을 수행합니다.

name=[value]...

...할당 문이 셸 변수 또는 배열 인덱스에 값을 할당하는 상황에서 += 연산자를 사용하여 변수의 이전 값에 추가하거나 추가할 수 있습니다.정수 속성이 설정된 변수에 +=을 적용하면 값이 산술식으로 평가되고 변수의 현재 값에 추가되며, 이 값도 평가됩니다.복합 할당을 사용하여 +=을 배열 변수에 적용하면(=을 사용할 때와 마찬가지로) 변수의 값이 설정되지 않으며, 새 값이 배열의 최대 인덱스(인덱스 배열의 경우)보다 큰 값으로 배열에 추가되거나 연관 배열에서 추가 키-값 쌍으로 추가됩니다.문자열 값 변수에 적용하면 값이 확장되고 변수 값에 추가됩니다.

다음과 같이 들여쓰기 내에서 필요에 따라 (백슬래시를 사용하지 않고) 새 줄로 구분하고 새 줄을 제거하면 됩니다.

예:

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

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

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

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

선 연속은 구문의 교묘한 사용을 통해서도 달성할 수 있습니다.

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.

변수의 경우:

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.

변수의 경우 다른 접근 방식:

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.

Voila!

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

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

제가 해결한 방법은 메시지를 여기 문서로 옮기는 것입니다(@tripleee 제안대로).하지만 여기에 있는 문서는 stdin이 되기 때문에 다시 읽어야 합니다. 저는 다음과 같은 접근법을 사용했습니다.

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

은 이는다같장있습다니점이은과음▁that다▁advantage있니습▁this▁has▁the라는 장점이 있습니다.$message추가 공백이나 줄 바꿈 없이 문자열 상수로 정확하게 사용할 수 있습니다.

위의 실제 메시지 줄은 다음과 같이 접두사가 붙습니다.tab각각의 문자, 여기 문서 자체에 의해 벗겨집니다(사용 때문에).<<-) 마지막에 줄 바꿈이 남아 있습니다. 줄 바꿈은 다음으로 대체됩니다.tr띄엄띄엄

또한 새 줄을 제거하지 않으면 새 줄은 다음과 같이 나타납니다."$message"확장되었습니다.경우에 따라 주변의 이중 따옴표를 제거하여 해결할 수 있습니다.$message하지만 메시지는 더 이상 단일 인수가 아닙니다.

어떤 종류의 위험을 수용할 것인지, 데이터를 얼마나 잘 알고 신뢰할 것인지에 따라 보간법을 사용할 수 있습니다.

$: 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

@tripleee's에 이어printf예제(+1):

LONG_STRING=$( printf '%s' \
    'This is the string that never ends.' \
    ' Yes, it goes on and on, my friends.' \
    ' My brother started typing it not knowing what it was;' \
    " and he'll continue typing it forever just because..." \
    ' (REPEAT)' )

echo $LONG_STRING

This is the string that never ends. Yes, it goes on and on, my friends. My brother started typing it not knowing what it was; and he'll continue typing it forever just because... (REPEAT)

그리고 우리는 문장 사이에 명시적인 공간을 포함했습니다. 예를 들어 "' Yes또한 변수 없이 수행할 수 있는 경우:

echo "$( printf '%s' \
    'This is the string that never ends.' \
    ' Yes, it goes on and on, my friends.' \
    ' My brother started typing it not knowing what it was;' \
    " and he'll continue typing it forever just because..." \
    ' (REPEAT)' )"

This is the string that never ends. Yes, it goes on and on, my friends. My brother started typing it not knowing what it was; and he'll continue typing it forever just because... (REPEAT)

끝이 없는 노래에 대한 인정

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

    echo "continuation \
    lines"
>continuation     lines

작은 따옴표를 사용하고 문자열을 연결합니다.

    echo 'continuation' \
    'lines'
>continuation lines

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

이것은 아마도 당신의 질문에 대한 답이 아닐 것이지만 어쨌든 당신은 그것이 유용하다는 것을 알게 될 것입니다.

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

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

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

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당신의 길을 따라가게 될 것입니다.

작동 방식에 대한 자세한 내용은 python 참조를 참조하십시오.

사용하는 경우$'...'또는"$(...)"혼란스럽다면 다른 질문(구성별로 하나씩)을 하십시오.다른 사용자들이 링크된 참조를 가질 수 있도록 찾거나 묻는 질문에 대한 링크를 제공하는 것이 좋을 수 있습니다.

언급URL : https://stackoverflow.com/questions/7316107/how-to-split-strings-over-multiple-lines-in-bash

반응형