Как нулевое заполнение последовательности целых чисел в bash, чтобы все имели одинаковую ширину?

Мне нужно закодировать некоторые значения,

for i in $(seq $first $last)
do
    does something here
done

Для $first и $last, мне нужно, чтобы она имела фиксированную длину 5. Итак, если входной файл 1, мне нужно добавить нули впереди, чтобы он стал 00001. Например, он работает до 99999, но длина должна быть 5.

Например: 00002, 00042, 00212, 012312 и т.д.

Любая идея о том, как я могу это сделать?

Ответ 1

В вашем конкретном случае, хотя, вероятно, проще всего использовать флаг -f для seq, чтобы заставить его форматировать числа, когда он выводит список. Например:

for i in $(seq -f "%05g" 10 15)
do
  echo $i
done

выдаст следующий результат:

00010
00011
00012
00013
00014
00015

В общем случае bash имеет printf как встроенный, поэтому вы можете выводить вывод с нулями следующим образом:

$ i=99
$ printf "%05d\n" $i
00099

Вы можете использовать флаг -v для сохранения вывода в другой переменной:

$ i=99
$ printf -v j "%05d" $i
$ echo $j
00099

Обратите внимание, что printf поддерживает немного другой формат seq, поэтому вам нужно использовать %05d вместо %05g.

Ответ 2

Легче еще вы можете сделать

for i in {00001..99999}; do
  echo $i
done

Ответ 3

Если конец последовательности имеет максимальную длину отступов (например, если вы хотите, чтобы 5 цифр и команда были "seq 1 10000" ), чем вы можете использовать флаг "-w" для seq - он добавляет саму себя.

seq -w 1 10

изготовлять

01
02
03
04
05
06
07
08
09
10

Ответ 4

используйте printf с "% 05d", например.

printf "%05d" 1

Ответ 5

Очень просто использовать printf

[jaypal:~/Temp] printf "%05d\n" 1
00001
[jaypal:~/Temp] printf "%05d\n" 2
00002

Ответ 6

Используйте awk следующим образом:

awk -v start=1 -v end=10 'BEGIN{for (i=start; i<=end; i++) printf("%05d\n", i)}'

ВЫВОД:

00001
00002
00003
00004
00005
00006
00007
00008
00009
00010

Update:

В качестве чистой альтернативы bash вы можете сделать это, чтобы получить тот же вывод:

for i in {1..10}
do
   printf "%05d\n" $i
done

Таким образом, вы можете избежать использования внешней программы seq, которая НЕ доступна для всех ароматов * nix.

Ответ 7

Я выкладываю вывод с большим количеством цифр (нулей), чем мне нужно, тогда используйте хвост, чтобы использовать только количество цифр, которые я ищу. Обратите внимание, что вы должны использовать "6" в хвосте, чтобы получить последние пять цифр:)

for i in $(seq 1 10)
do
RESULT=$(echo 00000$i | tail -c 6)
echo $RESULT
done

Ответ 8

Если вы хотите N цифр, добавьте 10 ^ N и удалите первую цифру.

for (( num=100; num<=105; num++ ))
do
  echo ${num:1:3}
done

Вывод:

01
02
03
04
05

Ответ 9

Это будет работать также:

for i in {0..9}{0..9}{0..9}{0..9}
do
  echo "$i"
done

Ответ 10

Другой путь:

zeroos="000"
echo 

for num in {99..105};do
 echo ${zeroos:${#num}:${#zeroos}}${num}
done

Так что простая функция для преобразования любого числа будет:

function leading_zero(){

    local num=$1
    local zeroos=00000
    echo ${zeroos:${#num}:${#zeroos}}${num} 

}

Ответ 11

1.) Создайте последовательность чисел 'seq' от 1 до 1000 и зафиксируйте ширину '-w' (ширина определяется длиной конечного числа, в данном случае 4 цифры на 1000).

2.) Кроме того, выберите, какие номера вы хотите, используя "sed -n" (в этом случае мы выбираем номера 1-100).

3.) "эхо" каждого номера. Числа хранятся в переменной "i", доступ к которой осуществляется с помощью "$".

Плюсы: этот код довольно чистый.

Минусы: 'seq' не свойственен всем системам Linux (насколько я понимаю)

for i in 'seq -w 1 1000 | sed -n '1,100p''; 
do 
    echo $i; 
done

Ответ 12

Если вы просто добавляете числа с нулями для достижения фиксированной длины, просто добавьте ближайшее кратное 10, например. для 2 цифр добавьте 10 ^ 2, затем удалите первую 1 перед отображением вывода.

Это решение работает для заполнения/форматирования отдельных чисел любой длины или целой последовательности чисел с использованием цикла for.

# Padding 0s zeros:
# Pure bash without externals eg. awk, sed, seq, head, tail etc.
# works with echo, no need for printf

pad=100000      ;# 5 digit fixed

for i in {0..99999}; do ((j=pad+i))
    echo ${j#?}
done

Протестировано на Mac OSX 10.6.8, Bash ver 3.2.48

Ответ 13

Один из способов без использования внешнего процесса - это манипулирование строками, в общем случае это будет выглядеть так:

#start value
CNT=1

for [whatever iterative loop, seq, cat, find...];do
   # number of 0s is at least the amount of decimals needed, simple concatenation
   TEMP="000000$CNT"
   # for example 6 digits zero padded, get the last 6 character of the string
   echo ${TEMP:(-6)}
   # increment, if the for loop does not provide the number directly
   TEMP=$(( TEMP + 1 ))
done

Это хорошо работает и в WSL, где разветвление - очень тяжелая операция. У меня был список 110000 файлов, использование printf "%06d" $NUM заняло более 1 минуты, решение, приведенное выше, заняло около 1 секунды.