모든 너비가 동일하도록 bash에서 정수 시퀀스를 0으로 채우는 방법은 무엇입니까?


426

일부 값을 반복해야합니다.

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

내용 $first$last, I는 입력 인 경우는 고정 길이 5 그럴 필요 1나는 그것이가되도록 앞의 예에서는 0을 추가해야 00001. 99999예를 들어 반복 되지만 길이는 5 여야합니다.

예 : 00002, 00042, 00212, 012312앞뒤로 너무.

내가 어떻게 할 수 있는지에 대한 아이디어가 있습니까?


22
정답은 다음과 같습니다. seq-w 1 99999. 옵션 -w는 출력 길이를 일정하게 유지하고 가장 짧은 숫자를 0으로 채 웁니다.
Bruno von Paris


여기에 많은 답변 for variable in $(something to generate the numbers); do ...이 권장 되지만 숫자 목록이 길면 문제가됩니다. 사용하는 것이 훨씬 더 효율적 something to generate the numbers | while read -r variable; do ...입니다. 파일 등에서 행을 읽는 것에 대해 설명하는 mywiki.wooledge.org/DontReadLinesWithFor 도 참조하십시오 . 그러나 일부 인수도 여기에 적용됩니다.
tripleee

답변:


710

특정 경우 에는 목록을 출력 할 때 숫자를 형식화하기 위해 -f플래그를 사용하는 것이 가장 쉬운 방법 일 것입니다 seq. 예를 들면 다음과 같습니다.

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

다음과 같은 출력이 생성됩니다.

00010
00011
00012
00013
00014
00015

더 일반적으로, bashprintfA가 내장 당신이 제로와 패드의 출력을 다음 수 있도록 같이

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

-v플래그를 사용하여 다른 변수에 출력을 저장할 수 있습니다 .

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

공지 사항 printf에 약간 다른 형식을 지원 seq사용할 필요가 있으므로 %05d대신 %05g.


5
%05g%05d나를 위해 고정시키는 대신 . "00026""00022"를 제공했습니다 . 감사!
Ed Manet 2013

12
훌륭하고 포괄적 인 답변. 하나의 작은 수정 : 엄격히 말하면 형식 문자 seq하위 집합 을 지원합니다 . 것을 printf지원 (그 부분 집합이 포함되어 g있지만 d). 문자의 동작 dg미묘하게한다는 점에서 다르다 d해석은 0같은 숫자 문자열 -prefixed 진수 반면, 숫자, 소수에 변환을 g소수로 취급 그들. (@EdManet : 그렇기 때문에 '00026'이 '00022'로 바 why d). 또 다른 것은 가치의 대한 언급은 : seq -w않습니다 자동으로 생성 된 넓은 수에 따라 출력 번호의 제로 패딩을.
mklement0

이것은 16 진 문자 목록을 생성하는 데 도움이되었습니다. for (( i = 0; i <= 0xffffffff; i++ )) do printf "%08x\n" $i ; done >> hex.txt8 자리 16 진수 목록을 생성했습니다. 감사.
cde

seq --help: "FORMAT은 'double'유형의 하나의 인수를 인쇄하는 데 적합해야합니다. FIRST, INCREMENT 및 LAST가 모두 최대 정밀도 PREC를 갖는 고정 소수점 10 진수 인 경우 기본값은 % .PRECf이고 그렇지 않은 경우 % g입니다." 가능한 변환 지정 자는 efgaEFGA입니다.
x-yuri

133

더 쉽게 당신은 그냥 할 수 있습니다

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

16
Bash 버전 4.1.2 (CentOS 6)에서는 작동하지만 버전 3.2.25 (CentOS 5)에서는 실패합니다. 나는 이것이 훨씬 더 미학적으로 즐거운 방법이라는 데 동의합니다!
Mike Starov

1
작품,하지만 내 떠들썩한 파티에 제로 패딩 문자열을 제공하지 않습니다
user2707001

Mac (Bash 4.4)에서는 숫자가 채워지지 않습니다. CentOS & SuSE에서는 훌륭하게 작동합니다!
Stefan Lasiewski

이것은 Bash와 함께 macOS에서 잘 작동합니다4.4.23(1)-release
Whymarrh

슬프게도 OS X 중 하나에 배쉬 5 작동하지 않습니다
gotofritz

91

시퀀스의 끝이 최대 패딩 길이를 갖는 경우 (예를 들어, 5 자리 숫자를 원하고 명령이 "seq 1 10000"인 경우) seq에 "-w"플래그를 사용할 수있는 것보다 패딩 자체가 추가됩니다.

seq -w 1 10

생산액

01
02
03
04
05
06
07
08
09
10

7
이것은 분명히 정답입니다. 업 보트가 적은 이유는 무엇입니까? 😳
adius

5
패딩은 도달하려는 최대 수에 따라 달라지기 때문에 쉽습니다. 이것이 매개 변수라면, 당신은 얼마나 많은 제로가 될지 미리 알 수 없습니다
guillem

5
이것은 지정된 고정 길이를 제공하지 않으며 결과는 모두 동일한 길이입니다.
Ceisc

78

"% 05d"와 함께 printf를 사용하십시오. 예 :

printf "%05d" 1

18

매우 간단한 사용 printf

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

12

다음과 같이 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

최신 정보:

순수한 bash 대안으로 동일한 출력을 얻기 위해이 작업을 수행 할 수 있습니다.

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

당신이 수있는이 방법을 피하기 외부 프로그램 사용 seq이다 사용할 수 없습니다 * nix에서 스크립트의 모든 맛에 있습니다.


1
과제 awk's BEGIN를 사용할 필요가 없도록 진술 을 사용할 수 있습니다 heredoc.
jaypal 싱

@JaypalSingh : 고맙습니다, 좋은 지적입니다. 내 답변을 업데이트했습니다.
anubhava

9

출력보다 더 많은 자릿수 (0)로 출력을 채운 다음 꼬리를 사용하여 찾고있는 자릿수 만 사용하십시오. 마지막 다섯 자리를 얻으려면 꼬리에 '6'을 사용해야합니다 :)

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

tail의 -c 인수에 올바른 수의 자리를 사용하려면 'echo -n 00000 $ i'를 사용할 수 있습니다. 이는 문자 꼬리 중 하나 인 개행을 출력하지 않기 때문에 필요합니다. 이 답변에서 1 위를 차지하십시오. 수행중인 작업에 따라 줄 바꿈이 남아 있으면 결과에 영향을 줄 수 있습니다.
Ceisc

루프에서 변수를 다듬기 위해 외부 프로세스를 사용하는 것은 다소 비효율적입니다. 쉘의 매개 변수 확장 기능을 대신 사용할 수 있습니다 . Bash에는 인덱스로 특정 하위 문자열을 추출하는 기능이 있거나 원하는 너비와 일치하는 패턴으로 접두사 및 접미사 대체를 사용할 수 있지만 약간의 전후가 필요합니다.
tripleee

4

N 자리를 원하면 10 ^ N을 더하고 첫 번째 자리를 삭제하십시오.

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

산출:

01
02
03
04
05

2

이것은 또한 작동합니다 :

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

좋은 해결책! 깨끗하고 읽기 쉽고 추가 프로그램이 필요하지 않습니다.
조나단 크로스

2

다른 방법 :

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} 

}

1

외부 프로세스 분기를 사용하지 않는 한 가지 방법은 문자열 조작입니다. 일반적인 경우에는 다음과 같습니다.

#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 doesn't provide the number directly
   TEMP=$(( TEMP + 1 ))
done

이것은 포크 작업이 정말 힘든 WSL에서도 잘 작동합니다. 나는 printf "%06d" $NUM1 분이 넘는 시간을 사용하여 110000 개의 파일 목록을 가지고 있었고 위의 솔루션은 약 1 초 만에 실행되었습니다.


0

1.) 1에서 1000 사이의 숫자 시퀀스 'seq'를 작성하고 너비 '-w'를 고정하십시오 (너비는 끝 숫자의 길이에 의해 결정되며이 경우 1000의 경우 4 자리).

2.) 또한 'sed -n'을 사용하여 원하는 숫자를 선택하십시오 (이 경우 숫자 1-100을 선택합니다).

3) 각 숫자의 '에코'. 숫자는 변수 'i'에 저장되며 '$'를 사용하여 액세스합니다.

장점 :이 코드는 매우 깨끗합니다.

단점 : 'seq'는 모든 Linux 시스템에 고유하지 않습니다 (알다시피)

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

0

고정 길이를 얻기 위해 숫자를 0으로 채우는 경우 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에서 테스트되었습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.