programing

공백이 있는 여러 줄 문자열(삽입된 부분 보존)

iphone6s 2023. 4. 17. 21:30
반응형

공백이 있는 여러 줄 문자열(삽입된 부분 보존)

다음과 같은 파일에 미리 정의된 텍스트를 쓰고 싶습니다.

text="this is line one\n
this is line two\n
this is line three"

echo -e $text > filename

나는 다음과 같은 것을 기대하고 있다.

this is line one
this is line two
this is line three

하지만 이것만은 알고 있습니다.

this is line one
 this is line two
 this is line three

의 각각 each 뒤에 이 없다고 확신한다\n지만여여여 간간?? ?????

이 목적을 위해서는 유전자가 더 편리할 것 같다.명령어 인터프리터 프로그램(: ex 또는 cat)에 여러 명령을 전송하기 위해 사용됩니다.

cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage

" " 뒤에 오는 <<정지할 장소를 나타냅니다.

이러한 행을 파일로 송신하려면 , 다음의 순서에 따릅니다.

cat > $FILE <<- EOM
Line 1.
Line 2.
EOM

다음 행을 변수에 저장할 수도 있습니다.

read -r -d '' VAR << EOM
This is line 1.
This is line 2.
Line 3.
EOM

이 변수 인 '이러다'에 됩니다.VAR.

인쇄할 때 변수 주변에 따옴표를 기억해 두지 않으면 줄 바꿈 문자를 볼 수 없습니다.

echo "$VAR"

게다가 들여쓰기를 사용하면, 코드에서 한층 더 두드러지게 할 수 있습니다.에는 그냥 'A'를해 주세요.- 후에<<탭이 표시되지 않도록 합니다.

read -r -d '' VAR <<- EOM
    This is line 1.
    This is line 2.
    Line 3.
EOM

그러나 코드 들여쓰기에 공백이 아닌 탭을 사용해야 합니다.

문자열을 변수에 넣으려면 다음과 같은 간단한 방법이 있습니다.

USAGE=$(cat <<-END
    This is line one.
    This is line two.
    This is line three.
END

)

탭('\t')으로 문자열을 들여쓰면 들여쓰기가 제거됩니다.공백으로 들여쓰면 들여쓰기가 그대로 남습니다.

메모: 마지막 닫는 괄호는 다른 행에 있는 것이 중요합니다.END텍스트는 줄에 직접 표시되어야 합니다.

echo는 전달된 인수 사이에 공백을 추가합니다. $text 분할의 을 받기 에, 「변수 전개와 단어 분할」의 대상이 됩니다.echo츠키다

echo -e "this" "is" "line" "one\n" "this" "is" "line" "two\n"  ...

'이것'은 '이것'입니다.하고 따옴표를 붙일 수 .$text하려면 : " " " " :

text="this is line one
this is line two
this is line three"

echo "$text" > filename

또는 를 사용할 수 있습니다.printfecho:

printf "%s\n" "this is line one" "this is line two" "this is line three" > filename

»bash브레이스 확장을 지원하며 다음 작업도 수행할 수 있습니다.

printf "%s\n" "this is line "{one,two,three} > filename

bash 스크립트에서는 다음과 같이 동작합니다.

#!/bin/sh

text="this is line one\nthis is line two\nthis is line three"
echo -e $text > filename

또는 다음과 같이 입력합니다.

text="this is line one
this is line two
this is line three"
echo "$text" > filename

cat filename은 다음과 같습니다.

this is line one
this is line two
this is line three

모든 행을 올바르게 삽입하고 싶었기 때문에 더 많은 솔루션을 찾았습니다.

  1. 하면 .echo:

    echo    "this is line one"   \
        "\n""this is line two"   \
        "\n""this is line three" \
        > filename
    

    「 「 」를."\n"\줄 끝에

  2. 외에 '먹다'를 사용할 .printf높이기 )echo

    printf '%s\n' \
        "this is line one"   \
        "this is line two"   \
        "this is line three" \
        > filename
    
  3. 또 다른 솔루션은 다음과 같습니다.

    text=''
    text="${text}this is line one\n"
    text="${text}this is line two\n"
    text="${text}this is line three\n"
    printf "%b" "$text" > filename
    

    또는

    text=''
    text+="this is line one\n"
    text+="this is line two\n"
    text+="this is line three\n"
    printf "%b" "$text" > filename
    
  4. 또 다른 솔루션은 혼합하여 실현됩니다.printf ★★★★★★★★★★★★★★★★★」sed

    if something
    then
        printf '%s' '
        this is line one
        this is line two
        this is line three
        ' | sed '1d;$d;s/^    //g'
    fi
    

    들여쓰기 수준을 코드로 하드코드하기 때문에 이와 같이 포맷된 코드를 리팩터링하는 것은 쉽지 않습니다.

  5. 도우미 함수와 몇 가지 변수 대체 트릭을 사용할 수 있습니다.

    unset text
    _() { text="${text}${text+
    }${*}"; }
    # That's an empty line which demonstrates the reasoning behind 
    # the usage of "+" instead of ":+" in the variable substitution 
    # above.
    _ ""
    _ "this is line one"
    _ "this is line two"
    _ "this is line three"
    unset -f _
    printf '%s' "$text"
    

변수에 여러 줄 문자열을 할당하는 방법은 다음과 같습니다(예상으로는 적절합니다).

read -r -d '' my_variable << \
_______________________________________________________________________________

String1
String2
String3
...
StringN
_______________________________________________________________________________

밑줄 수는 두 경우 모두 동일합니다(여기서는 80).

나는 이 답을 찾으면서 들었지만 다른 명령어로 파이프로 연결하기를 원했다.지정된 답변은 맞지만 파이프로 연결하려면 다음과 같이 여러 줄 문자열 앞에 파이프를 연결해야 합니다.

echo | tee /tmp/pipetest << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage

이를 통해 여러 줄의 문자열을 가질 수 있지만 후속 명령어 stdin에도 넣을 수 있습니다.

읽기 어렵다:

이것은 내 일반적인 취향으로는 너무 bash처럼 보인다:) (읽기 어렵다).

cat << EndOfMessage
This is line 1.
This is line 2.
Line 3.
EndOfMessage

보다 뛰어난 읽기 쉬운 기능:

좀 더 피토닉한 것을 구해 봅시다(이것은 여전히 bash입니다).

text="this is line one
      this is line two
      this is line three\n"
dedent text
printf "$text"             # print to screen
printf "$text" > file.txt  # print to a file

아... 그게 더 낫네요.:) 여기서 사용하는 Python의 기능이 생각납니다.

이 있다dedent을 사용하다

dedent() {
    local -n reference="$1"
    reference="$(echo "$reference" | sed 's/^[[:space:]]*//')"
}

화면 출력 예시:

this is line one
this is line two
this is line three

콜 With OUT 。dedent text 은 다음과

this is line one
      this is line two
      this is line three

''textdedent 함수 내부에서 수정된 내용이 함수 외부의 변수에 영향을 미치도록 합니다.

자세한 내용, 설명 및 참조는 여기서 다른 답변을 참조하십시오.python의 textwrap dedent in bash

처음 시도에서 문제가 있습니다.

OP의 인용문(중요점을 추가):

의 각각 each 뒤에 이 없다고 확신한다\n하지만 여분의 공간은 어떻게 나오나요?

처음 시도한 것은 다음과 같습니다.

text="this is line one\n
this is line two\n
this is line three"
echo -e $text

두 번째 줄과 세 번째 줄 앞에 여분의 공간이 있었잖아요, 왜요?

추론과 실험으로 보아 내 결론은echo는, 행의 말미에 있는 실제의 새로운 행(실제로 눌렀을 때에 취득한 행)을 스페이스로 변환합니다.따라서 이 공간은 각 행 바로 에 표시됩니다.\n이치노

각 입니다.\스트링 따옴표 안에 있는 행의 끝에는 다음과 같이 표시됩니다.

text="this is line one\n\
this is line two\n\
this is line three"

echo -e "$text"

후행 백슬래시 앞에 공백을 두지 마십시오(다음과 같이).text="this is line one\n \그렇지 않으면 공간이 출력으로 바로 돌아가 추가 공간에서도 동일한 문제가 발생합니다.

아니면, 그냥 제 기술을 사용해서dedent위의 기능에는 코드와 함께 들여쓰기를 할 수 있는 기능이 추가되어 있어 매우 예쁘고 멋지고 읽기 쉬워 보입니다.

그것을 하는 방법은 여러 가지가 있다.저는 움푹 들어간 줄을 SED에 꽂는 것이 좋습니다.

printf_strip_indent() {
   printf "%s" "$1" | sed "s/^\s*//g" 
}

printf_strip_indent "this is line one
this is line two
this is line three" > "file.txt"

이 대답은 마테우스 피오트로스키의 대답에 근거하고 있었지만, 조금 더 세련되었다.

다음과 같이 하면 동작합니다.

AA='first line
\nsecond line 
\nthird line'
echo $AA
output:
first line
second line
third line

간단한 한 줄 연결은 때때로 유용할 수 있기 때문에 언급합니다.

# for bash

v=" guga "$'\n'"   puga "

# Just for an example.
v2="bar "$'\n'"   foo "$'\n'"$v"

# Let's simplify the previous version of $v2.
n=$'\n'
v3="bar ${n}   foo ${n}$v"

echo "$v3" 

이런 일이 생길 거야

막대기후우구가푸가

선두 및 말미 공백은 모두 다음 기간 동안 올바르게 유지됩니다.

echo "$v3" > filename

또는 텍스트를 공백으로 들여쓰기:

#!/bin/sh

sed 's/^[[:blank:]]*//' >filename <<EOF
    this is line one
    this is line two
    this is line three
EOF

동일하지만 변수 사용:

#!/bin/sh

text="$(sed 's/^[[:blank:]]*//' << whatever
    this is line one
    this is line two
    this is line three
)"

echo "$text" > filename

;-)

언급URL : https://stackoverflow.com/questions/23929235/multi-line-string-with-extra-space-preserved-indentation

반응형