배쉬 연속 라인
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)"
It also works well in contexts where you want to embed nontrivial pieces of shell script in another language where the host language's syntax won't let you use a here document, such as in a Makefile
or Dockerfile
.
printf '%s\n' >./myscript \
'#!/bin/sh` \
"echo \"G'day, World\"" \
'date +%F\ %T' && \
chmod a+x ./myscript && \
./myscript
You can use bash arrays
$ str_array=("continuation"
"lines")
then
$ echo "${str_array[*]}"
continuation lines
there is an extra space, because (after bash manual):
If the word is double-quoted,
${name[*]}
expands to a single word with the value of each array member separated by the first character of the IFS variable
So set IFS=''
to get rid of extra space
$ IFS=''
$ echo "${str_array[*]}"
continuationlines
I came across a situation in which I had to send a long message as part of a command argument and had to adhere to the line length limitation. The commands looks something like this:
somecommand --message="I am a long message" args
The way I solved this is to move the message out as a here document (like @tripleee suggested). But a here document becomes a stdin, so it needs to be read back in, I went with the below approach:
message=$(
tr "\n" " " <<- END
This is a
long message
END
)
somecommand --message="$message" args
This has the advantage that $message
can be used exactly as the string constant with no extra whitespace or line breaks.
Note that the actual message lines above are prefixed with a tab
character each, which is stripped by here document itself (because of the use of <<-
). There are still line breaks at the end, which are then replaced by dd
with spaces.
Note also that if you don't remove newlines, they will appear as is when "$message"
is expanded. In some cases, you may be able to workaround by removing the double-quotes around $message
, but the message will no longer be a single argument.
You could simply separate it with newlines (without using backslash) as required within the indentation as follows and just strip of new lines.
Example:
echo "continuation
of
lines" | tr '\n' ' '
Or if it is a variable definition newlines gets automatically converted to spaces. So, strip of extra spaces only if applicable.
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
This isn't exactly what the user asked, but another way to create a long string that spans multiple lines is by incrementally building it up, like so:
$ greeting="Hello"
$ greeting="$greeting, World"
$ echo $greeting
Hello, World
Obviously in this case it would have been simpler to build it one go, but this style can be very lightweight and understandable when dealing with longer strings.
However, if you have indented code, it doesn't work out so well:
echo "continuation \ lines" >continuation lines
Try with single quotes and concatenating the strings:
echo 'continuation' \
'lines'
>continuation lines
Note: the concatenation includes a whitespace.
Depending on what sort of risks you will accept and how well you know and trust the data, you can use simplistic variable interpolation.
$: 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
In certain scenarios utilizing Bash's concatenation ability might be appropriate.
Example:
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
From the PARAMETERS section of the Bash Man page:
name=[value]...
...In the context where an assignment statement is assigning a value to a shell variable or array index, the += operator can be used to append to or add to the variable's previous value. When += is applied to a variable for which the integer attribute has been set, value is evaluated as an arithmetic expression and added to the variable's current value, which is also evaluated. When += is applied to an array variable using compound assignment (see Arrays below), the variable's value is not unset (as it is when using =), and new values are appended to the array beginning at one greater than the array's maximum index (for indexed arrays) or added as additional key-value pairs in an associative array. When applied to a string-valued variable, value is expanded and appended to the variable's value.
This probably doesn't really answer your question but you might find it useful anyway.
The first command creates the script that's displayed by the second command.
The third command makes that script executable.
The fourth command provides a usage example.
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
Note that if you really want to use this script, it makes more sense to move the executable script into ~/bin
so that it will be in your path.
Check the python reference for details on how textwrap.dedent
works.
If the usage of $'...'
or "$(...)"
is confusing to you, ask another question (one per construct) if there's not already one up. It might be nice to provide a link to the question you find/ask so that other people will have a linked reference.
참고URL : https://stackoverflow.com/questions/7316107/bash-continuation-lines
'development' 카테고리의 다른 글
HList는 복잡한 튜플 작성 방법에 지나지 않습니까? (0) | 2020.06.20 |
---|---|
“#define _GNU_SOURCE”는 무엇을 의미합니까? (0) | 2020.06.20 |
네비게이션 컨트롤러 스택, 서브 뷰 또는 모달 컨트롤러를 사용하지 않고 뷰 컨트롤러의 애니메이션 변경? (0) | 2020.06.20 |
Ember.js의 뷰와 컴포넌트 (0) | 2020.06.20 |
BigDecimal equals () 대 compareTo () (0) | 2020.06.20 |