programing

Bash에서 변수에 유전 값을 할당하려면 어떻게 해야 합니까?

showcode 2023. 4. 15. 09:42
반응형

Bash에서 변수에 유전 값을 할당하려면 어떻게 해야 합니까?

다음 여러 줄 문자열(따옴표 포함)이 있습니다.

abc'asdf"
$(dont-execute-this)
foo"bar"''

Bash에서 유전자를 사용하여 변수에 할당하려면 어떻게 해야 합니까?

새 라인을 보존해야 합니다.

줄에 있는 캐릭터들을 벗어나고 싶지 않아, 짜증나...

의 불필요한 사용을 피할 수 있습니다.cat일치하지 않는 따옴표를 더 잘 처리할 수 있습니다.

$ read -r -d '' VAR <<'EOF'
abc'asdf"
$(dont-execute-this)
foo"bar"''
EOF

에코할 때 변수를 따옴표로 묶지 않으면 새 행이 손실됩니다.견적을 내자면 다음과 같습니다.

$ echo "$VAR"
abc'asdf"
$(dont-execute-this)
foo"bar"''

소스 코드의 가독성을 위해 들여쓰기를 사용하려는 경우, 작은 선 뒤에 대시를 사용합니다.들여쓰기는 탭만 사용하여 수행해야 합니다(스페이스 없음).

$ read -r -d '' VAR <<-'EOF'
    abc'asdf"
    $(dont-execute-this)
    foo"bar"''
    EOF
$ echo "$VAR"
abc'asdf"
$(dont-execute-this)
foo"bar"''

대신 결과 변수의 내용에서 탭을 유지하려면 다음 위치에서 탭을 제거해야 합니다.IFS. 여기 doc의 터미널 마커)EOF)는 들여쓰지 마십시오.

$ IFS='' read -r -d '' VAR <<'EOF'
    abc'asdf"
    $(dont-execute-this)
    foo"bar"''
EOF
$ echo "$VAR"
    abc'asdf"
    $(dont-execute-this)
    foo"bar"''

탭은 V명령줄에 삽입할 수 있습니다.에디터를 사용하고 있는 경우는, 어느 에디터에 의해서도 기능하거나, 탭을 스페이스로 자동적으로 변환하는 기능을 무효로 할 필요가 있습니다.

$()를 사용하여 출력을 할당합니다.cat다음과 같이 변수를 지정합니다.

VAR=$(
cat <<'END_HEREDOC'
abc'asdf"
$(dont-execute-this)
foo"bar"''
END_HEREDOC
)

# this will echo variable with new lines intact
echo "$VAR"
# this will echo variable without new lines (changed to space character)
echo $VAR

END_ERDOC 시작 시 반드시 단일 따옴표로 구분하십시오.이렇게 하면 유전자의 함량이 확대되는 것을 막을 수 있기 때문에dont-execute-this는 실행되지 않습니다.

끝의 세습 구분 기호는END_HEREDOC회선상에 혼자 있어야 합니다(종료 괄호 포함).)다음 줄에 있습니다.)

덕분에.@ephemient정답을 찾아주세요.

이것은 데니스 방식의 변형으로, 대본에서 더 우아해 보입니다.

함수 정의:

define(){ IFS='\n' read -r -d '' ${1} || true; }

사용방법:

define VAR <<'EOF'
abc'asdf"
$(dont-execute-this)
foo"bar"''
EOF

echo "$VAR"

즐거운 시간 되세요.

p.s.가 지원하지 않는 셸의 'read loop' 버전을 만들었습니다.read -d.와 연동해야 합니다.set -eu페어링되지 않은 백틱도 있지만 테스트가 잘 되지 않았습니다.

define(){ o=; while IFS="\n" read -r a; do o="$o$a"'
'; done; eval "$1=\$o"; }
VAR=<<END
abc
END

stdin을 상관하지 않는 것(즉, 할당)으로 리다이렉트하기 때문에 동작하지 않는다.

export A=`cat <<END
sdfsdf
sdfsdf
sdfsfds
END
` ; echo $A

작동하지만, 그 안에 백틱이 있어서 이걸 못 쓰게 할 수도 있어요.또한 backticks를 사용하는 것도 피해야 합니다.명령어 대체 표기법을 사용하는 것이 좋습니다.$(..).

export A=$(cat <<END
sdfsdf
sdfsdf
sdfsfds
END
) ; echo $A

새로운 라인을 보존하는 솔루션은 아직 없습니다.

이것은 사실이 아닙니다.아마 당신은 에코의 행동에 현혹되고 있을 것입니다.

echo $VAR # strips newlines

echo "$VAR" # preserves newlines

Neil의 답변을 분기하면, 종종 변수가 전혀 필요하지 않고 변수와 거의 같은 방식으로 함수를 사용할 수 있으며 인라인 또는 인라인보다 훨씬 읽기 쉽습니다.read를 기반으로 합니다.

$ complex_message() {
  cat <<'EOF'
abc'asdf"
$(dont-execute-this)
foo"bar"''
EOF
}

$ echo "This is a $(complex_message)"
This is a abc'asdf"
$(dont-execute-this)
foo"bar"''

배열은 변수이므로 이 경우 맵파일이 동작합니다.

mapfile y <<'z'
abc'asdf"
$(dont-execute-this)
foo"bar"''
z

그러면 이렇게 인쇄할 수 있습니다.

printf %s "${y[@]}"

제가 이걸 처음 올렸다는 게 믿기지 않아요.

과 @ @ @ @ @ @ @ @ @ @ @ @ 좀 좀 좀 @ 。mapfile어레이만 읽는 게 아니라

다음 사항을 고려하십시오.

#!/bin/bash
mapfile -d '' EXAMPLE << 'EOF'
Hello
こんにちは
今晩は
小夜なら
EOF
echo -n "$EXAMPLE"

산출량:

안녕하세요.こんにちは今晩は小夜なら

$''는 에 입니다.mapfile는 "구분되지 않음"을 의미합니다.

굳이 쓸 cat어레이를 재결합하는 번거로움이 없습니다.

게다가 다음과 같은 메리트가 있습니다.

$ echo $EXAMPLE
Hello こんにちは 今晩は 小夜なら

@Zombo 메서드에서는 수신할 수 없습니다.

mapfile y <<'z'
abc'asdf"
$(dont-execute-this)
foo"bar"''
z
echo $y
abc'asdf"

보너스

head -c -1퍼포먼스가 저하되지 않는 방법으로 마지막 새 라인을 삭제할 수도 있습니다.

unset EXAMPLE
mapfile -d '' EXAMPLE < <(head -c -1 << EOF
Hello
こんにちは
今晩は
小夜なら
EOF
)
printf "%q" "$EXAMPLE"
$'Hello\nこんにちは\n今晩は\n小夜なら'

변수에 유전적인 값을 할당하다

VAR="$(cat <<'VAREOF'
abc'asdf"
$(dont-execute-this)
foo"bar"''
VAREOF
)"

명령어 인수로 사용되다

echo "$(cat <<'SQLEOF'
xxx''xxx'xxx'xx  123123    123123
abc'asdf"
$(dont-execute-this)
foo"bar"''
SQLEOF
)"

dimo414의 답변 덕분에 그의 뛰어난 솔루션이 어떻게 기능하는지 알 수 있으며 텍스트에 인용문이나 변수를 쉽게 넣을 수 있습니다.

출력 예

$ ./test.sh

The text from the example function is:
  Welcome dev: Would you "like" to know how many 'files' there are in /tmp?

  There are "      38" files in /tmp, according to the "wc" command

test.sh

#!/bin/bash

function text1()
{
  COUNT=$(\ls /tmp | wc -l)
cat <<EOF

  $1 Would you "like" to know how many 'files' there are in /tmp?

  There are "$COUNT" files in /tmp, according to the "wc" command

EOF
}

function main()
{
  OUT=$(text1 "Welcome dev:")
  echo "The text from the example function is: $OUT"
}

main

저는 NULL이 들어간 문자열을 읽어야 한다는 것을 깨달았습니다.그 때문에, 여기에 당신이 던지는 어떤 것도 읽어낼 수 있는 솔루션이 있습니다.실제로 NULL을 취급하고 있는 경우는 16진수 레벨로 취급할 필요가 있습니다.

$ cat > read.dd.

read.dd() {
     buf= 
     while read; do
        buf+=$REPLY
     done < <( dd bs=1 2>/dev/null | xxd -p )

     printf -v REPLY '%b' $( sed 's/../ \\\x&/g' <<< $buf )
}

실증:

$ . read.dd.sh
$ read.dd < read.dd.sh
$ echo -n "$REPLY" > read.dd.sh.copy
$ diff read.dd.sh read.dd.sh.copy || echo "File are different"
$ 

GREEDOC의 예(^J, ^M, ^I 포함):

$ read.dd <<'HEREDOC'
>       (TAB)
>       (SPACES)
(^J)^M(^M)
> DONE
>
> HEREDOC

$ declare -p REPLY
declare -- REPLY="  (TAB)
      (SPACES)
(^M)
DONE

"

$ declare -p REPLY | xxd
0000000: 6465 636c 6172 6520 2d2d 2052 4550 4c59  declare -- REPLY
0000010: 3d22 0928 5441 4229 0a20 2020 2020 2028  =".(TAB).      (
0000020: 5350 4143 4553 290a 285e 4a29 0d28 5e4d  SPACES).(^J).(^M
0000030: 290a 444f 4e45 0a0a 220a                 ).DONE

(imho) 꽤 우아하고 UUOC를 피할 수 있는 방법이 있습니다.

  VAR=$(sed -e 's/[ ]*\| //g' -e '1d;$d' <<'--------------------'
      | 
      | <!DOCTYPE html>
      | <html>
      |   <head>
      |     <script src='script.js'></script>
      |   </head>
      |   <body>
      |     <span id='hello-world'></span>
      |   </body>
      | </html>
      | 
--------------------
    )

'|' 문자는 여백을 정의하며 여백 오른쪽에 있는 공백만 인쇄 문자열에서 사용됩니다.'1d;$d'첫 번째 줄과 마지막 줄을 제거합니다. 이 행은 내용 주위에 맨 위 및 맨 아래 여백으로 추가됩니다.원하는 수준까지 모두 들여쓸 수 있습니다. 단, 이 경우 하이픈 집합인 GREEDOC 구분 기호를 제외합니다.

echo "$VAR"

# prints

<!DOCTYPE html>
<html>
  <head>
    <script src='script.js'></script>
  </head>
  <body>
    <span id='hello-world'></span>
  </body>
</html>
$TEST="ok"
read MYTEXT <<EOT
this bash trick
should preserve
newlines $TEST
long live perl
EOT
echo -e $MYTEXT

언급URL : https://stackoverflow.com/questions/1167746/how-to-assign-a-heredoc-value-to-a-variable-in-bash

반응형