Napsal jsem velmi základní skript substituce příkazů, který je uveden níže:
#!/bin/bash files=$(ls *.fastq); echo $files
Adresář obsahuje spoustu souboru .fastq a chci k jejich výstupu použít příkaz echo
Výše uvedený skript vypíše soubory fastq s mezerou mezi každým názvem souboru fastq.
Když to používám tímto způsobem
#!/bin/bash files=$(ls *.fastq); echo "$files"
vytiskne výsledky na nové řádky.
Proč je to tak? Je to něco společného se nahrazením příkazu?
Děkujeme
Odpovědět
Při odkazování na proměnnou to je obecně vhodné uvést jeho jméno v uvozovkách. Tím se zabrání reinterpretaci všech speciálních znaků v citovaném řetězci – kromě $
, `
(backquote) a \
(uniknout). Ponechání $
jako zvláštního znaku v uvozovkách umožňuje odkaz na citovanou proměnnou („$ variable“), tj. Nahradit proměnnou její hodnotou.
Použít uvozovky, aby se zabránilo rozdělení slova. Argument uzavřený do uvozovek se představuje jako jedno slovo, i když obsahuje oddělovače mezer.
např.
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"
Uzavření argumentů do příkazu echo v uvozovkách je nutné pouze tehdy, když je problém s rozdělením nebo zachováním mezer.
Další informace a příklady najdete zde
Odpovědět
Máte nové řádky, protože ls
je staví na samostatné řádky. Nové řádky zmizí bez uvozovek, protože shell (bash) předá každý necitovaný text oddělený mezerou příkazu jako samostatný argument.
Poznámka: Substituci příkazu provádí shell, nikoli ls
, takže nepotřebujete ls
.
Proto můžete
#!/bin/bash echo *.fastq
nebo
#!/bin/bash files="*.fastq" echo "$files"
Komentáře
Odpovědět
Když odkazujete na proměnnou bez uvozovek (např. echo $files
), shell rozdělí hodnotu na mezery a předá každý výraz jako samostatnou možnost příkazového řádku. S novými řádky se zachází stejně jako s jinými prázdnými znaky. Program echo
vůbec nevidí znaky nového řádku; pouze získá řadu řetězců, z nichž každý má jeden název souboru.
Když odkazujete na proměnnou v uvozovkách (např. echo "$files"
), shell nedělá žádné rozdělení mezer; místo toho předá celou hodnotu, beze změny, jako jediný argument. Program echo
obdrží jeden dlouhý řetězec, který obsahuje znaky nového řádku.
Proměnné stranou, toto je stejné chování jako u uvozovek kolem doslovných hodnot. Pokud napíšete echo foo bar
, mezery jsou odstraněny shellem a echo
pouze získá řetězce foo
a bar
a vytiskne tyto řetězce s jednou mezerou mezi nimi, protože takto je kódováno pro kombinování více argumentů. Pokud napíšete echo "foo bar"
, echo
získá jediný řetězec foo bar
a vytiskne jej tak, jak je.
ls
bude mít stejný výstup jakols -x
kdy na tty, a jakols -1
když ne. Proto použijtels -x
k získání toho, co chcete.