Как обнулить числовые переменные в zsh (а может быть, и в bash?)

В zsh, когда мне нужно создать кучу файлов с помощью zsh, я обычно делаю что-то вроде:

for x in $(seq 1 1000); do .....; done

Это работает нормально, я получаю файлы с именами foo-1.txt .. foo-1000.txt.
Однако эти файлы плохо сортируются, поэтому я хотел бы дополнить нулем переменную $x, получив таким образом имена foo-0001.txt .. foo-1000.txt.

Как это сделать в зш? (и бонусный вопрос, как это сделать в bash?)


person ervingsb    schedule 15.03.2012    source источник


Ответы (6)


Используйте флаг -w для seq (в любой оболочке):

$ seq -w 1 10
01
02
03
04
05
06
07
08
09
10
person Mat    schedule 15.03.2012
comment
seq -w 001 005 # колодки - person zzapper; 10.05.2017

Для справки, если у вас нет контроля над генерацией числовых значений, вы можете выполнить заполнение с помощью:

% value=314
% echo ${(l:10::0:)value}
0000000314
% echo $value
314
person Francisco    schedule 15.04.2013
comment
Видя, что ${(l... не очень удобен для поисковых систем, поищите это в разделе Флаги расширения параметров в zshexpn(1). Также можно использовать парные разделители, чтобы сделать синтаксис немного более интуитивным: ${(l{ 10}{0})значение}. - person Roman Odaisky; 23.07.2013
comment
Как ни странно, zmv не понимает эту форму, хотя скобки работают нормально: ${(l(10)(0))value}. - person Roman Odaisky; 23.07.2013

Вы можете использовать раскрытие фигурных скобок в bash:

$ for n in file-{0001..1000}.txt; do echo $n; done
file-0001.txt
file-0002.txt
file-0003.txt
file-0004.txt
file-0005.txt
file-0006.txt
file-0007.txt
file-0008.txt
file-0009.txt
file-0010.txt
...
file-0998.txt
file-0999.txt
file-1000.txt

В зш тоже работает.

person glenn jackman    schedule 15.03.2012

в Зш:

% my_num=43
% echo ${(l(5)(0))my_num}
00043
person Konstantin Nikitin    schedule 10.02.2020

Работает в bash (не знаю для zsh):

echo foo{0000-1000}.txt 
person user unknown    schedule 15.03.2012

  1. printf
    Использование printf для заполнения нулями работает в любой оболочке:

    $ printf 'foo%03d.txt\n' $(seq 4)
    foo001.txt
    foo002.txt
    foo003.txt
    foo004.txt
    
    $           printf  'foo%03d.txt\n' {1..4}       # works in bash, ksh, zsh.
    $ n=4;      printf  'foo%03d.txt\n' {1..$n}      # only ksh, zsh
    $ n=4; eval printf '"foo%03d.txt\n" {1..'"$n"'}' # workaround needed for bash
    
  2. Используйте раскрытие фигурных скобок (только bash и zsh сохраняют начальные нули, ksh - нет).

    $ printf '%s\n' foo{1..004}.txt
    foo001.txt
    foo002.txt
    foo003.txt
    foo004.txt
    
person ImHere    schedule 09.06.2017