Mam zmienną wieloliniową i chcę tylko pierwszy wiersz w tej zmiennej. Poniższy skrypt demonstruje problem:
#!/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
Pytanie: Dlaczego ${STRINGTEST%%$'\n'*}
zwraca pierwszy wiersz po umieszczeniu po echo
poleceniu, ale zastępuje nowe wiersze spacjami po umieszczeniu po przypisaniu?
$'...'
zamiast bash.Odpowiedzi:
Być może istnieje inny sposób archiwizacji tego, co chcesz zrobić, ale to działa
źródło
$STRINGTEST
nie zawierają spacji ani symboli wieloznacznych. Zauważ też, że puste linie (jak w pierwszym wierszu tej zmiennej) są ignorowane.STRINGTEST=(${STRINGTEST[@]})
nie ma sensu i jest równoważne temu,STRINGTEST=($STRINGTEST)
ponieważSTRINGTEST
wcześniej było zdefiniowane jako zmienna skalarna (nie macierzowa ).może nie być najbardziej wydajny, ale jedna wkładka ...
źródło
firstLine=`echo "${test_var}" | sed -n 1p
działa także jeśli mają powód do korzystania sed zamiast (np Oznacza to można jednocześnie wykonać wymianę do linii:echo "${test_var}" | sed -nE '1 s/# *(.*)/\1/p'
.Ten kod działa dla mnie ze wszystkimi wersjami bash, które wypróbowałem między 2.05b a 4.3. Bardziej prawdopodobne jest, że próbowałeś uruchomić ten skrypt z inną powłoką, która nie obsługuje
$'...'
formy cytowania.Że
$'...'
składnia nie jest standardowash
składnia (jeszcze) i obsługiwane tylko (od 2015-05-22 i AFAIK) przezksh93
(gdzie to pochodzi)zsh
,bash
ostatnie wersjemksh
ish
czy nowsze wersje FreeBSD .Mój zakład jest to, że próbowałeś uruchomić ten skrypt
sh
zamiastbash
i twójsh
oparty jest na wersjiash
,pdksh
,yash
lubksh88
, które nie obsługują jeszcze.Jeśli chcesz uczynić ten kod POSIX 2008 kompatybilnym, musisz go napisać:
Następnie możesz go zinterpretować przez dowolną powłokę zgodną z POSIX, jak również
bash
dowolną cieńszą / szybszą, taką jak twojash
.(i pamiętaj, że pozostawienie zmiennej niecytowanej w kontekście listy ma szczególne znaczenie w powłokach podobnych do Bourne'a).
źródło
To działa dla mnie:
Działa również w przypadku pustych linii:
źródło
read
raz przejść do prostej zmiennej (zamiastreadarray
indeksowania plus).Z wbudowanym Bash
read
i tutaj:Korzystanie z rozszerzania parametrów POSIX:
źródło