Kiedy robię
str="Hello World\n===========\n"
Dostaję też \n
wydrukowany. Jak mogę mieć wtedy nowe linie?
Kiedy robię
str="Hello World\n===========\n"
Dostaję też \n
wydrukowany. Jak mogę mieć wtedy nowe linie?
Odpowiedzi:
W bash
możesz użyć składni
str=$'Hello World\n===========\n'
Pojedyncze cudzysłowy poprzedzone a $
to nowa składnia, która pozwala wstawiać sekwencje specjalne w ciągach znaków.
Również printf
wbudowany pozwala zapisać wynikowy wynik w zmiennej
printf -v str 'Hello World\n===========\n'
Oba rozwiązania nie wymagają podpowłoki.
Jeśli poniżej musisz wydrukować ciąg, powinieneś użyć podwójnych cudzysłowów, jak w poniższym przykładzie:
echo "$str"
ponieważ gdy drukujesz ciąg bez cudzysłowów, znak nowej linii jest konwertowany na spacje.
str=$'Hello World\n===========\n'
? zmienne podstawienie?
zsh
i ksh
; jednak NIE jest zgodny z POSIX.
str=$"My $PET eats:\n$PET food"
? To podejście działa w przypadku podwójnych cytatów
Możesz wstawić dosłowne znaki nowej linii w pojedynczych cudzysłowach (w dowolnej powłoce w stylu Bourne / POSIX).
str='Hello World
===========
'
W przypadku ciągu wielowierszowego dokumenty tutaj są często wygodne. Ciąg jest podawany jako dane wejściowe do polecenia.
mycommand <<'EOF'
Hello World
===========
EOF
Jeśli chcesz zapisać ciąg w zmiennej, użyj cat
polecenia w podstawieniu polecenia. Znaki nowego wiersza na końcu ciągu zostaną usunięte przez podstawienie polecenia. Jeśli chcesz zachować ostatnie znaki nowej linii, umieść korek na końcu i zdejmij go później. W powłokach zgodnych z POSIX możesz pisać, str=$(cat <<'EOF'); str=${str%a}
a następnie heredoc właściwy, ale bash wymaga, aby heredoc pojawił się przed nawiasem zamykającym.
str=$(cat <<'EOF'
Hello World
===========
a
EOF
); str=${str%a}
W ksh, bash i zsh możesz użyć $'…'
cytowanego formularza, aby rozwinąć znaki odwrotnego ukośnika w cudzysłowach.
str=$'Hello World\n===========\n'
str=$(cat <<'EOF')
nie działa tak, jak jest. )
Musi zostać umieszczony w następnym wierszu po końcu dokumentu EOF
... ale mimo to traci końcowy znak nowej linii z powodu polecenia Podstawienie.
\n
instancje bash
podczas przechwytywania dokumentu tutaj w zmiennej, rozważ IFS= read -r -d '' str <<'EOF'...
jako alternatywę dla podejścia ograniczającego (patrz moja odpowiedź).
Czy używasz „echa”? Spróbuj „echo -e”.
echo -e "Hello World\n===========\n"
echo
automatycznie doda jeden, chyba że podasz -n. (Jednak głównym celem pytania jest to, jak przekształcić te nowe wiersze w zmienną).
bash
, echo -e
czyni pracę na OS X - to dlatego, że echo
jest bash wbudowane (zamiast zewnętrznego wykonywalny) i że wbudowane obsługuje -e
. (Jako wbudowany, powinien działać na wszystkich platformach, na których działa bash; nawiasem mówiąc, echo -e
działa ksh
i zsh
również). Jednak zewnętrzne echo
narzędzie w systemie OS X - /bin/echo
- rzeczywiście nie obsługuje -e
.
Jeśli wiele razy potrzebujesz nowego wiersza w skrypcie, możesz zadeklarować zmienną globalną zawierającą nowy wiersz. W ten sposób możesz używać go w ciągach cudzysłowów (zmienne rozszerzenia).
NL=$'\n'
str="Hello World${NL} and here is a variable $PATH ===========${NL}"
$''
wymagałaby podpowłoki?
"My dog eats:${NL}dog food"
Aby uzupełnić wspaniałe istniejące odpowiedzi:
Jeśli używasz bash
i wolisz używać rzeczywistych znaków nowej linii dla czytelności , read
to kolejna opcja przechwytywania dokumentu tutaj w zmiennej , która (podobnie jak inne rozwiązania tutaj) nie wymaga użycia podpowłoki.
# Reads a here-doc, trimming leading and trailing whitespace.
# Use `IFS= read ...` to preserve it (the trailing \n, here).
read -r -d '' str <<'EOF' # Use `IFS= read ...` to preserve the trailing \n
Hello World
===========
EOF
# Test: output the variable enclosed in "[...]", to show the value's boundaries.
$ echo "$str"
[Hello World
===========]
-r
zapewnia, że read
nie interpretuje danych wejściowych (domyślnie traktowałby ukośniki specjalne, ale jest to rzadko potrzebne).
-d ''
ustawia separator „rekordu” na pusty ciąg, powodując read
odczytanie całego wejścia naraz (zamiast tylko jednej linii).
Zauważ, że pozostawiając $IFS
(wewnętrzny separator pól) na wartości domyślnej $' \t\n'
(spację, tabulator, nową linię), wszelkie początkowe i końcowe białe znaki są przycinane od wartości przypisanej do $str
, w tym nowej linii tutaj-doc.
(Zauważ, że chociaż treść tutaj-doc zaczyna się od linii po ograniczniku początkowym ( 'EOF'
tutaj), nie zawiera wiodącej nowej linii).
Zwykle jest to pożądane zachowanie, ale jeśli chcesz tę końcową linię, użyj IFS= read -r -d ''
zamiast po prostu read -r -d ''
, ale zwróć uwagę, że wszystkie początkowe i końcowe białe znaki są następnie zachowywane.
(Należy pamiętać, że przejście IFS=
bezpośrednio do read
polecenia oznacza, że przypisanie działa tylko podczas tego polecenia, więc nie ma potrzeby przywracania poprzedniej wartości).
Użycie dokumentu tutaj pozwala również opcjonalnie użyć wcięcia w celu uruchomienia ciągu wielowierszowego dla zapewnienia czytelności:
# Caveat: indentation must be actual *tab* characters - spaces won't work.
read -r -d '' str <<-'EOF' # NOTE: Only works if the indentation uses actual tab (\t) chars.
Hello World
===========
EOF
# Output the variable enclosed in "[...]", to show the value's boundaries.
# Note how the leading tabs were stripped.
$ echo "$str"
[Hello World
===========]
Umieszczenie -
między znakiem <<
otwierającym doc tutaj i otwierającym ( 'EOF'
tutaj) powoduje, że wiodące znaki tabulacji są usuwane z ciała doc doc, a nawet ogranicznika zamykającego, ale należy pamiętać, że działa to tylko z rzeczywistymi znakami tabulacji , a nie spacjami, więc jeśli edytor tłumaczy naciśnięcia klawiszy tabulacji na spacje, potrzebna jest dodatkowa praca.
musisz to zrobić w ten sposób:
STR=$(echo -ne "Hello World\n===========\n")
Aktualizacja:
Jak zauważył Fred, w ten sposób stracisz końcowe „\ n”. Aby przypisać zmienną z rozwiniętymi sekwencjami odwrotnego ukośnika, wykonaj:
STR=$'Hello World\n===========\n\n'
przetestujmy to:
echo "[[$STR]]"
daje nam teraz:
[[Hello World
===========
]]
Pamiętaj, że $ „” jest inny niż $ „”. Drugi wykonuje tłumaczenie zgodnie z bieżącymi ustawieniami narodowymi. Dla deital patrz sekcja CYTOWANIE w man bash
.
#!/bin/bash
result=""
foo="FOO"
bar="BAR"
result+=$(printf '%s' "$foo")$'\n'
result+=$(printf '%s' "$bar")$'\n'
echo "$result"
printf '%s' "$result"
wynik:
FOO
BAR
FOO
BAR
result+=$foo$'\n'
? $(printf %s "$foo")
zmniejszyłby końcowe znaki nowego wiersza, $foo
jeśli takie istnieją.