В bash, как я могу добавлять целые числа с ведущими нулями и поддерживать указанный буфер

Например, я хочу считать от 001 до 100. Это означает, что нулевой буфер будет начинаться с 2, 1, а затем, в конечном итоге, с 0, когда он достигнет 100 или больше.

ex: 001 002 ... 010 011 ... 098 099 100

Я мог бы сделать это, если бы числа имели заранее определенное количество нулей с printf "% 02d" $ i. Но это статично, а не динамично, и в моем примере это не сработает.


person readdit    schedule 07.07.2010    source источник
comment
Добро пожаловать в StackOverflow. Обязательно выберите ответ (с помощью галочки), который, по вашему мнению, лучше всего решает ваш вопрос, чтобы другие могли извлечь пользу из изложенных знаний.   -  person SiegeX    schedule 07.07.2010
comment
возможный дубликат Как обнулить последовательность целых чисел в bash, чтобы все они имели одинаковую ширину?   -  person Ciro Santilli 新疆再教育营六四事件ۍ    schedule 24.07.2015


Ответы (5)


Если под статикой или динамикой вы имеете в виду, что хотите использовать переменную для ширины, вы можете сделать это:

$ padtowidth=3
$ for i in 0 {8..11} {98..101}; do printf "%0*d\n" $padtowidth $i; done
000
008
009
010
011
098
099
100
101

Звездочка заменяется значением переменной, которой она соответствует в списке аргументов (в данном случае $padtowidth).

В противном случае единственная причина, по которой ваш пример не работает, заключается в том, что вы используете «2» (возможно, как если бы это было максимальное применяемое заполнение), когда оно должно быть «3» (как в моем примере), поскольку это значение является итоговым результатом ширина (не только ширина площадки).

person Dennis Williamson    schedule 07.07.2010
comment
Да, вы, вероятно, правы, используя zsh в сценарии bash. Я упустил из виду ваш метод. Ваш и SiegeX отлично работают для того, что мне нужно. Спасибо. - person readdit; 08.07.2010

Если в вашей системе он есть, попробуйте seq с опцией -w (--equal-width):

$ seq -s, -w 1 10
01,02,03,04,05,06,07,08,09,10

$ for i in `seq -w 95 105` ; do echo -n " $i" ; done
095 096 097 098 099 100 101 102 103 104 105
person mob    schedule 07.07.2010
comment
Это хорошая идея, но не совсем такая, как я ее себе представлял. Он будет буферизован с 3 нулями тогда и только тогда, когда он достигнет целого числа с 3 цифрами (например: 100). Если он достигнет всего 99, он будет включать только буфер с двумя нулями. Извините, я не уточнил. - person readdit; 07.07.2010
comment
Йоханнес. Да ты прав. Этот метод тоже работает правильно. Не знаю, что запускал вчера. Спасибо. - person readdit; 08.07.2010
comment
Этот ответ следует принять как правильный. Самое элегантное решение. :) Спасибо, моб! - person Pradeep Gollakota; 18.12.2013

В Bash версии 4 (используйте bash -version) вы можете использовать расширение скобок. Если поставить 0 перед любым пределом, числа будут дополнены нулями.

echo {01..100} # 001 002 003 ...
echo {03..100..3} # 003 006 009 ...
person Johannes Schaub - litb    schedule 07.07.2010
comment
Для этого требуется Bash 4. В более ранних версиях не используется дополнение в фигурных скобках. - person Dennis Williamson; 07.07.2010
comment
Спасибо Йоханнесу и Деннису. Да, я обнаружил, что для этого требуется bash 4. Который я не использую. Я обнаружил, что могу использовать zsh таким же образом. for i in $ (zsh -c echo {$ FROM .. $ TO}) do echo $ i; done Работает нормально, и не нужно писать слишком сложные сценарии. - person readdit; 07.07.2010
comment
@readdit: вызов zsh из сценария bash кажется довольно расточительным. Либо напишите весь сценарий в zsh (он имеет высокий уровень совместимости с Bash, хотя некоторые вещи достаточно отличаются, что вам придется внести несколько изменений), либо используйте встроенные функции bash, такие как метод printf, который я показываю в моем отвечать. Есть и другие методы, которые также будут работать с использованием только встроенных команд оболочки. - person Dennis Williamson; 08.07.2010

#!/bin/bash

max=100; 

for ((i=1;i<=$max;i++)); do 
    printf "%0*d\n" ${#max} $i
done

Приведенный выше код автоматически дополнит ваши числа правильным числом 0 в зависимости от того, сколько цифр содержит максимальное / конечное значение. Все, что вам нужно сделать, это изменить переменную max, и она сделает все остальное.

Примеры:

макс = 10

01
02
03
04
05
06
07
08
09
10

макс = 100

001
002
003
004
005
006
...
097
098
099
100

макс = 1000

0001
0002
0003
0004
0005
0006
...
0997
0998
0999
1000
person SiegeX    schedule 07.07.2010

Если вам нужно заполнить значения до номера переменной с помощью переменного заполнения:

$values_count=514;
$padding_width=5;

for i in 0 `seq 1 $(($values_count - 1))`; do printf "%0*d\n" $padding_width $i; done;

Это распечатает 00000, 00001, ... 00513. (Я не нашел ни одного из текущих ответов, соответствующих моей потребности)

person khaverim    schedule 13.03.2017