bash : 변수의 첫 줄을 변수에 할당


11

여러 줄 변수가 있으며 해당 변수의 첫 번째 줄만 원합니다. 다음 스크립트는 문제를 보여줍니다.

#!/bin/bash

STRINGTEST="Onlygetthefirstline
butnotthesecond
orthethird"

echo "  Take the first line and send to standard output:"
echo ${STRINGTEST%%$'\n'*}
#   Output is as follows:
# Onlygetthefirstline

echo "  Set the value of the variable to the first line of the variable:"
STRINGTEST=${STRINGTEST%%$'\n'*}

echo "  Send the modified variable to standard output:"
echo $STRINGTEST
#   Output is as follows:
# Onlygetthefirstline butnotthesecond orthethird

질문 : 명령 ${STRINGTEST%%$'\n'*}뒤에 배치 할 때 첫 번째 줄을 반환하는 이유는 무엇입니까? echo그러나 할당 후에 배치 할 때 줄 바꿈을 공백으로 바꾸는 이유는 무엇 입니까?


1
재현 할 수 없습니다. 예상대로 작동합니다.
Peque

1
2.05b, 3.1, 3.2, 4.0, 4.1, 4.2, 4.3 중 어느 것으로도 재생할 수 없습니다. $'...'bash 대신 지원하지 않는 쉘로 실행하려고하는 것과 같은 사용자 오류처럼 들립니다.
Stéphane Chazelas

답변:


8

어쩌면 원하는 것을 보관하는 다른 방법이있을 수 있지만 작동합니다.

#!/bin/bash

STRINGTEST="
Onlygetthefirstline
butnotthesecond
orthethird
"

STRINGTEST=(${STRINGTEST[@]})
echo "${STRINGTEST[0]}"

줄에 $STRINGTEST공백이나 와일드 카드가 포함 되어 있지 않다고 가정합니다 . 또한 변수의 첫 번째 줄에서와 같이 빈 줄은 무시됩니다.
Stéphane Chazelas

3
또한 사용 STRINGTEST=(${STRINGTEST[@]})하는 것은 의미가 없으며 이전에 스칼라 ( 배열 아님) 변수 로 정의 된 STRINGTEST=($STRINGTEST)이후 와 같습니다 . STRINGTEST
Stéphane Chazelas

10

가장 효율적이지 않지만 하나의 라이너 일 수 있습니다 ...

firstLine=`echo "${multiLineVariable}" | head -1`

2
나는 명확성과 간결함을 좋아합니다.
피터-복원 모니카

firstLine=`echo "${test_var}" | sed -n 1p대신 sed를 사용해야 할 이유가있는 경우 echo "${test_var}" | sed -nE '1 s/# *(.*)/\1/p'
에도이 기능

7

이 코드는 2.05b와 4.3 사이에서 시도한 모든 버전의 bash에서 작동합니다. $'...'인용 형식을 지원하지 않는 다른 쉘로 해당 스크립트를 실행하려고했을 가능성이 큽니다 .

$'...'구문은 표준 아닙니다 sh으로 (아직) 구문 만 (2015년 5월 22일 및 AFAIK 현재) 지원 ksh93(그것이 유래) zsh, bash최근의 버전 mkshsh의 FreeBSD 또는 최신 버전 .

내 좋은 방법은 당신이 그 스크립트를 실행하려고한다는 것 sh대신을 bash하고이 sh버전을 기반으로 ash, pdksh, yash또는 ksh88그게 아직 지원하지 않습니다.

해당 코드를 POSIX 2008과 호환되게하려면 다음 코드를 작성해야합니다.

STRINGTEST="Onlygetthefirstline
butnotthesecond
orthethird"

NL='
'
STRINGTEST=${STRINGTEST%%"$NL"*}
printf '%s\n' "$STRINGTEST"

그런 다음 POSIX 호환 쉘 bash이나 귀하의와 같은 더 빠르거나 빠른 쉘로 해석 할 수 있습니다 sh.

(그리고리스트 컨텍스트에서 인용되지 않은 변수를 남겨 두는 것은 Bourne과 같은 쉘에서 매우 특별한 의미가 있음을 기억하십시오).


또는 이전 버전의 bash 일 수 있습니다. 2.03으로 동작을 재현 할 수 있습니다.
Gilles 'SO- 악마 그만'

bash-2.03 (16 년 전에 릴리스)이 포함 된 마지막 지원 OS 인 @Gilles는 아마도 3 년 전에 EOL을 사용한 Solaris 8 일 것입니다. 그 가설은 거의 없을 것 같습니다.
Stéphane Chazelas

1

이것은 나를 위해 작동합니다 :

STRINGTEST="Some Text 1
Some Text 2
Some Text 3"

readarray -t lines < <(echo "$STRINGTEST")
echo "${lines[0]}"

그리고 빈 줄에도 적용됩니다.

STRINGTEST="
Some Text 1
Some Text 2
Some Text 3"

readarray -t lines < <(echo "$STRINGTEST")
echo "${lines[0]}"

하나가 프로세스 대체를 방해하는 경우 read간단한 readarray인덱싱 대신 간단한 변수로 한 번만 사용할 수 있습니다.
피터-복원 모니카

0

Bash 내장 read및 here-string으로 :

#!/usr/bin/env bash

STRINGTEST="
Some Text 1
Some Text 2
Some Text 3"


IFS=$'\n' read -r STRINGTEST <<<"$STRINGTEST"

POSIX 매개 변수 확장 사용 :

#!/usr/bin/env sh

STRINGTEST="
Some Text 1
Some Text 2
Some Text 3"

# Disables globing
set -f

# Field separator is newline only
IFS="
"

# No quotes, split lines as arguments because of IFS
set -- $STRINGTEST

# First argument is first line
STRINGTEST="$1"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.