Czy istnieje sposób na to, aby bash nie zjadał nowych linii w wyniku zamiany wstecz?
Na przykład:
var=`echo line one && echo line two`
echo $var
line one line two
Chcę to
var=`echo line one && echo line two` # plus some magic
echo $var
line one
line two
bash
Ekspansja wykonuje parametrów przed wykonaniem polecenia, powołując należy poinformowaćbash
, że chcesz wydrukować jeden ciąg, a nie 4 słowa (line
,one
,line
itwo
). Spróbuj:echo a <many spaces> b
iecho "a <many spaces> b"
. Spójrz również na tę odpowiedź .Mimo że @cyrus jest poprawny - tak naprawdę nie odpowiada na całe pytanie i nie ma wyjaśnienia, co się dzieje.
Przejdźmy więc to.
Nowe linie w ciągu
Najpierw określ oczekiwaną sekwencję bajtów:
Teraz użyj polecenia Podstawienie komendy (sekcja 3.5.4), aby spróbować przechwycić tę sekwencję bajtów:
Następnie wykonaj proste echo, aby sprawdzić sekwencję bajtów:
Wygląda na to, że pierwsza nowa linia została zastąpiona spacją, a druga nowa linia pozostała nienaruszona. Ale dlaczego ?
Przyjrzyjmy się, co się tu właściwie dzieje:
Po pierwsze, bash wykona rozszerzenie parametru powłoki (rozdział 3.5.3)
Następnie bash wykona dzielenie wyrazów (rozdział 3.5.7)
Następnie bash potraktuje to jako proste polecenie (rozdział 3.2.1)
Definicja pustych miejsc (sekcja 2 - Definicje)
Wreszcie bash powołuje się na echo (sekcja 4.2 - Bash Builtin Commands) polecenie wewnętrzne
Podsumowując, nowe wiersze są usuwane przez podział tekstu, a następnie echo dostaje 2 argumenty, „a” i „b”, a następnie wyprowadza je oddzielone spacjami i kończąc na nowej linii.
Robiąc to, co sugerował @cyrus (i pomijaj echo nowej linii za pomocą -n), wynik jest lepszy:
Nowe linie na końcu łańcucha
Wciąż jednak nie jest idealny, nowa linia zniknęła. Przyglądając się bliżej podstawieniu poleceń (sekcja 3.5.4) :
Teraz, gdy jest jasne, dlaczego nowa linia odchodzi, bash można oszukać. Aby to zrobić, dodaj dodatkowy ciąg na końcu i usuń go, gdy używasz zmiennej:
TL; DR
Dodaj dodatkową część na końcu danych wyjściowych i cytuj zmienne:
źródło
Umieściłbym mój mały dodatek w komentarzu do odpowiedzi cYrus, ale myślę, że nie mogę jeszcze komentować odpowiedzi. Powtórzę więc część jego odpowiedzi dla kompletności.
W pierwszym wierszu kodu dzieje się tak, że podstawienie wstecznego zjada końcowe znaki wyjściowe podstawionego polecenia, jak udokumentowano . Ale nie zjada nowej linii między twoimi dwiema liniami.
W drugim wierszu kodu następuje echo z dwoma argumentami, pierwszym i drugim wierszem. Cytując zmienną rozwiniętą, naprawisz to:
echo "$var"
Pozwoli to zachować nową linię między linią pierwszą a linią drugą. Iecho
domyślnie doda końcowy znak nowej linii, aby wszystko było w porządku.Teraz, jeśli chcesz zachować wszystkie końcowe znaki nowego wiersza w wyniku niektórych podstawień poleceń, obejście polega na dodaniu kolejnego wiersza wyniku, który możesz usunąć po podstawieniu polecenia, zobacz tutaj .
źródło