2012-01-09 1 views
261

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

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

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

т.д .: 00002, 00042, 00212, и так далее.

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

+10

Хороший ответ может быть: далее - вес 1 99999. Опция -w сохраняет выходной Длинна постоянные, утеплитель короткие номера с 0. –

+0

также переименовать файлы: HTTP: // stackoverflow.com/questions/55754/bash-script-to-pad-file-names –

ответ

440

В вашем конкретном случае, хотя это, вероятно, проще всего использовать -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.

+1

'% 05g' вместо'% 05d' исправил его для меня. «00026» _ давал мне «00022» _. Благодаря! –

+6

Отличный, исчерпывающий ответ. Одна небольшая коррекция: строго говоря, 'seq' поддерживает _subset_ символов формата. что 'printf' поддерживает (и что подмножества включают' g', но не 'd'). Поведение символов 'd' и' g' тонко отличается от того, что 'd' интерпретирует строки с 0-префиксными числами как _octal_ numbers и преобразует их в десятичные числа, тогда как' g' рассматривает их как десятичные числа. (@EdManet: вот почему «00026» превратился в «00022» с 'd'). Еще одна вещь, которую стоит упомянуть: 'seq -w' делает _automatic_ нулевое заполнение выходных чисел на основе самого широкого числа сгенерированных. – mklement0

+0

Это помогло мне генерировать список шестнадцатеричных символов. 'for ((i = 0; i <= 0xffffffff; i ++)) do printf"% 08x \ n "$ i; done >> hex.txt' создал 8-символьный шестнадцатеричный список. Благодарю. – cde

56

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

printf "%05d" 1 
13

Очень просто с помощью printf

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

Использование 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:

Как чисто Баш альтернатива вы можете сделать это, чтобы получить тот же результат:

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

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

+1

Мы можем использовать '' '' '' '' 'BEGIN''', чтобы нам не пришлось использовать назначение' heredoc'. –

+0

@JaypalSingh: Спасибо, парень, это хороший момент. Обновлен мой ответ. – anubhava

80

еще проще, вы можете просто сделать

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

Это работает с Bash версии 4.1.2 (CentOS 6), но не работает в версии 3.2.25 (CentOS 5). Я согласен с тем, что это гораздо более эстетичный способ сделать это! –

+0

Работает, но не дает нулевых заполненных строк на моем bash – user2707001

43

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

seq -w 1 10 

производит

01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
+2

Это, очевидно, правильный ответ. Почему у него так мало оборотов? – adius

+2

легко, потому что заполнение зависит от максимального количества, которое вы хотите достичь. Если это параметр, который вы никогда не знаете заранее, сколько нулей вы получите в – guillem

+1

Это не дает заданной фиксированной длины, просто результаты, которые являются всей длиной _same_. – Ceisc

5

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

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

Если вы хотите использовать правильное количество мест в аргументе -c хвоста, вы можете использовать «echo -n 00000 $ i», так как это останавливает вывод строки новой строки, которая является одним из хвостов символов, поэтому она нуждается в чтобы быть выше в этом ответе. В зависимости от того, что вы делаете, новая строка, если она оставлена, может повлиять на результаты. – Ceisc

2

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

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

Выход:

01 
02 
03 
04 
05