Napisałem bardzo podstawowy skrypt podstawiania poleceń, który jest poniżej:
#!/bin/bash files=$(ls *.fastq); echo $files
Katalog zawiera kilka plików .fastq i chcę po prostu użyć polecenia echo, aby je wyprowadzić
Powyższy sript wypisuje pliki fastq ze spacją między każdą nazwą pliku fastq.
Kiedy używam go w ten sposób
#!/bin/bash files=$(ls *.fastq); echo "$files"
wypisuje wyniki w nowych wierszach.
Dlaczego tak jest? Czy ma to coś wspólnego z podstawianiem poleceń?
Dzięki
Odpowiedź
Odwołując się do zmiennej, ogólnie zaleca się umieszczenie jego nazwy w cudzysłowie. Zapobiega to ponownej interpretacji wszystkich znaków specjalnych w ciągu cytowanym – z wyjątkiem $
, `
(odwrotny cudzysłów) i \
(ucieczka). Utrzymanie $
jako znaku specjalnego w podwójnych cudzysłowach umożliwia odwoływanie się do zmiennej w cudzysłowie („$ zmienna”), czyli zastąpienie zmiennej jej wartością.
Użyj podwójne cudzysłowy, aby zapobiec dzieleniu słów. Argument ujęty w podwójne cudzysłowy przedstawia się jako pojedyncze słowo, nawet jeśli zawiera separatory białych znaków.
np.
variable1="a variable containing five words" COMMAND This is $variable1 # Executes COMMAND with 7 arguments: # "This" "is" "a" "variable" "containing" "five" "words" COMMAND "This is $variable1" # Executes COMMAND with 1 argument: # "This is a variable containing five words"
Umieszczenie argumentów instrukcji echo w podwójnych cudzysłowach jest konieczne tylko wtedy, gdy problemem jest dzielenie słów lub zachowanie białych znaków.
Więcej informacji i przykładów znajdziesz tutaj
Odpowiedź
Masz znaki nowej linii, ponieważ ls
umieszcza je w osobnych wierszach. Nowe linie znikają bez cudzysłowów, ponieważ powłoka (bash) przekazuje do polecenia każdy niecytowany tekst oddzielony spacjami jako oddzielny argument.
Uwaga: podstawianie poleceń jest wykonywane przez powłokę, , a nie przez ls
, więc nie potrzebujesz ls
.
Dlatego możesz zrobić
#!/bin/bash echo *.fastq
lub
#!/bin/bash files="*.fastq" echo "$files"
Komentarze
Odpowiedz
Kiedy odwołujesz się do zmiennej bez cudzysłowów (np. echo $files
), powłoka dzieli wartość na białe znaki i przekazuje każdy termin jako oddzielną opcję wiersza poleceń. Nowe linie są traktowane tak samo, jak inne spacje. Program echo
w ogóle nie widzi znaków nowego wiersza; po prostu pobiera tablicę ciągów, z których każdy jest pojedynczą nazwą pliku.
do zmiennej w cudzysłowach (np. echo "$files"
), powłoka nie rozdziela białych znaków; zamiast tego przekazuje całą niezmodyfikowaną wartość jako pojedynczy argument. Program echo
otrzymuje jeden długi ciąg zawierający znaki nowego wiersza.
Pomijając zmienne, jest to to samo zachowanie, które uzyskuje się w przypadku cudzysłowów wokół wartości literałów. Jeśli napiszesz echo foo bar
, spacje zostaną usunięte przez powłokę, a echo
otrzyma tylko ciągi znaków foo
i bar
i „wydrukuje te ciągi z pojedynczą spacją między nimi, ponieważ tak to jest kodowane, aby łączyć wiele argumentów. Jeśli napiszesz echo "foo bar"
, echo
pobiera pojedynczy ciąg znaków foo bar
i wydrukuje go tak, jak jest.
ls
wyświetli to samo cols -x
do terminala, a na przykładls -1
, gdy nie. Dlatego użyjls -x
, aby uzyskać to, czego chcesz.