SPRINTF w skryptach shell?

Mam automatycznie generowany plik każdego dnia, który jest wywoływany przez skrypt powłoki. Ale problem, z którym się borykam, polega na tym, że automatycznie wygenerowany plik ma postać:

FILE_MM_DD.dat

... gdzie MM i DD są ciągami dwucyfrowymi miesiąca i dnia miesiąca.

Poszperałem trochę i sam to zrobiłem, ale nie wiem, jak stworzyć te niestandardowe ciągi używając tylko skryptów powłoki.

Aby było jasne, jestem świadomy funkcji daty w Bash, ale to, czego szukam, to odpowiednik funkcji SPRINTF w C.

Author: Manu R, 2010-12-07

3 answers

W Bash:

var=$(printf 'FILE=_%s_%s.dat' "$val1" "$val2")

Lub, odpowiednik i bliższy sprintf:

printf -v var 'FILE=_%s_%s.dat' "$val1" "$val2"

Jeśli Twoje zmienne zawierają wartości dziesiętne z początkowymi zerami, możesz je usunąć:

val1=008; val2=02
var=$(printf 'FILE=_%d_%d.dat' $((10#$val1)) $((10#$val2)))

Lub

printf -v var 'FILE=_%d_%d.dat' $((10#$val1)) $((10#$val2))

$((10#$val1)) wymusza wartość do bazy 10, więc %d w specyfikacji formatu nie uważa, że "08" jest nieprawidłową wartością ósemkową.

Jeśli używasz date (przynajmniej dla GNU date), możesz pominąć początkowe zera w następujący sposób:

date '+FILE_%-m_%-d.dat'

Dla kompletność, jeśli chcesz dodać zera wiodące, wyściełane do pewnej szerokości:

val1=8; val2=2
printf -v var 'FILE=_%04d_%06d.dat' "$val1" "$val2"

Lub o szerokościach dynamicznych:

val1=8; val2=2
width1=4; width2=6
printf -v var 'FILE=_%0*d_%0*d.dat' "$width1" "$val1" "$width2" "$val2"

Dodawanie początkowych zer jest przydatne do tworzenia wartości, które łatwo sortują i wyrównują w kolumnach.

 49
Author: Dennis Williamson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-13 23:00:44

Dlaczego nie używać programu printf z coreutils?

$ printf "FILE_%02d_%02d.dat" 1 2
FILE_01_02.dat
 8
Author: Daniel Böhmer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-07 14:50:56

Try:

sprintf() { local stdin; read -d '' -u 0 stdin; printf "$@" "$stdin"; }

Przykład:

$ echo bar | sprintf "foo %s"
foo bar
 1
Author: kenorb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-10-13 22:28:12