printf "file '%s'\n" *.m4a > list.txt
Ta syntaxe je funkční, ale detailně vzato chybná (nebo alespoň zavádějící) — zpětné lomítko má být ve dvojitých uvozovkách zdvojeno, i v nich totiž zůstává zvláštním znakem, na což bys narazil, kdybys v něm chtěl vypsat zpětné lomítko jako takové — to by tam muselo být čtyřikrát, protože jednou ho zredukuje bash a podruhé příkaz printf.
A nyní to vysvětlení: příkaz „printf“ je „vylepšené echo“; jeho první parametr je „formátovací řetězec“, který se většinou vypisuje na výstup tak, jak je, ale může obsahovat formátovací značky začínající procentem. Každá taková značka „načte“ jeden z dalších parametrů a zformátuje ho způsobem, který vyjadřuje; formátovací značka „%s“ znamená vypsat obsah parametru jako řetězec beze změny. Pokud po zpracování celého formátovacího řetězce ještě nějaké parametry zbudou, příkaz printf ty již zpracované zahodí a se zbytkem začne znovu. V tomto případě bash za „*.m4a“ dosadí seřazené názvy souborů s příponou „*.m4a“ a to jsou parametry, které bude printf číst. A protože formátovací řetězec obsahuje jen jednu formátovací značku, celý řetězec se zopakuje pro každý parametr. Příkaz printf také ve formátovacím řetězci interpretuje značky začínající zpětným lomítkem jako v tomto případě „\n“, za kterou dosadí znak konce řádky (na rozdíl od echo, printf konec řádky sám od sebe nepřidává). A přesměrování do souboru je snad jasné...
Pro jiné vysvětlení (možná srozumitelnější), zadej v bashi příkaz:
help printf
Osobně se snažím formátovací řetězec printf uvádět co nejvíc v apostrofech, protože se tím šetří problémy se zpětnými lomítky, ale pokud sám má obsahovat apostrof jako v tomto případě, je to problém, takže nejlepší řešení je všechna zpětná lomítka ve dvojitých uvozovkách zdvojit:
printf "file '%s'\\n" *.m4a > list.txt