제어 구문 예제_02 연속된 파일명을 가진 URL을 자동 생성해서 순서대로 내려받기

 
  • 출처 : 유닉스 리눅스 쉘스크립트 예제사전_한빛미디어

명령어: seq, printf, curl
키워드: 연속번호, URL, 내려받기
사용처: 파일명에 연속한 번호가 있는 그림 파일을 웹 서버에서 자동으로 내려받고 싶을 때


실행예제

$ ./number-file.sh  <------ URL을 자동 생성해서 내려받기함

스크립트

#!/bin/sh

url_template=http://www.example.org/download/img_%03d.jpg  #--- 1

# seq 명령어로 연속 번호 생성
for i in $(seq 10)  #------------------------------------------ 2
do
  url=$(printf "$url_template" $i)  #-------------------------- 3
  curl -O "$url"  #-------------------------------------------- 4
done

   

해설

이 스크립트는 셸 변수 url_template로 지정한 URL에서 파일명이 연속된 그림 파일을 웹 서버에서 순서대로 내려받습니다. 여기서 내려받고 싶은 파일이 다음과 같은 URL이라고 가정합니다.

  • http://www.example.org/download/img_001.jpg
  • http://www.example.org/download/img_002.jpg
  • http://www.example.org/download/img_003.jpg …

예제에서는 seq 명령어와 for문으로 img_(세 자리수).jpg라는 파일명을 생성합니다.

seq 명령어는 단순 증가(감소)하는 숫자열을 표시하는 명령어입니다. 사용하는 인수 개수에 따라 세 가지 사용법이 있습니다.

1 마지막 값만 지정
2 시작값과 종료값 지정
3 시작값과 증감, 종료값 지정

시작값과 증감은 생략하면 1이 됩니다.

  • seq 명령어 사용법

    사용법 설명 비고
    seq 5 1에서 5까지 하나씩 증가 생략된 시작값과 증감은 1
    seq 3 5 3에서 5까지 하니씩 증가 생략된 증감은 1
    seq 5 10 45 5에서 45까지 10씩 증가 없음
  • seq 명령어 실행 예: 시작값과 증감과 종료값 지정

    $ seq 5 10 45
    5
    15
    25
    35
    45
    

증감에는 음수값을 사용할 수도 있으므로 감소하는 숫자 열도 취득할 수 있습니다.

예제에서는 이런 seq 명령어로 반복 카운터를 작성합니다. 이런 방법은 두 가지 장점이 있습니다.

1 seq 명령어 옵션으로  편하게 카운터 작성 가능
2 반복 처리 고속화

일반적으로 셸 스크립트에서 반복 카운터로 연속된 숫자를 사용하고 싶을 때는 전통적으로 [파일1] 처럼 while 문에서 expr 명령어를 사용해서 카운터를 늘립니다.

  • 파일1 반복 카운터의 전통적 문법

      i=1
      while [ "$i" -le 10 ]
      do
          ($i를 사용한 처리)
          # 변수 i 증가
          i=$(expr $i + 1)
      done
    

하지만 이때 반복할 때마다 expr 명령어를 실행하므로 반복 횟수가 많으면 처리 속도가 늦어집니다. 예제처럼 seq 명령어 출력을 사용하면 반복할 때마다 expr 명령어로 더하지 않아도 되므로 처리 속도가 빨라지게 됩니다.

[파일2]는 1에서 1000까지 파일을 연속으로 작성하는 예제입니다. 파일 내려받기 확인 등의 목적으로 이런 파일을 작성하는 스크립트가 자주 사용됩니다. 이 스크립트는 필자 환경에서는 0.1초도 걸리지 않습니다. 한편, [파일1]처럼 while문으로 작성해서 expr 명령어로 카운터를 늘려가면 1.2초 정도 걸립니다. 이처럼 seq 명령어로 반복을 만들면 10배 이상 빨라지게 됩니다.

  • 파일2 seq 명령어를 사용하면 속도가 빠름

    #!/bin/sh
    
    for i in $(seq 1000)
    do
        echo "$i" > ${i}.txt
    done
    

그럼 예제를 봅시다. 1에서 내려받을 파일 URL을 지정합니다. 이때 연속 번호 부분은 %03d라는 printf 명령어로 지정한 서식 지정자로 작성합니다.

2에서 seq 명령어 출력을 for문에 지정합니다. 2부분은 구체적으로 적으면 다음처럼 동작합니다. 이렇게 해서 셸 변수 i에 순서대로 번호가 대입됩니다.

for i 1 2 3 4 5 6 7 8 9 10

3에서 셸 변수 url에 내려받을 그림 파일의 실제 URL을 대입합니다. 연속 번호 부분은 %03d이므로 i가 3이면 printf 명령어는

http://www.example.org/download/img_003.jpg

를 출력합니다. 이 출력을 명령어 치환 $( )으로 셸 변수 url에 대입합니다.

조합한 URL을 써서 4에서 curl 명령어로 파일을 내려받습니다. curl 명령어에 -O 옵션을 사용해서 URL 파일명대로 파일을 저장합니다.

이렇게 해서 seq 명령어와 for문을 조합해서 연속된 파일명을 생성하고 내려받습니다. 그 외에도 카운트하며 숫자를 포함한 문자열을 만드는 등 연속 번호 관련 처리에 응용할 수 있습니다.

   

주의사항

  • FreeBSD나 Mac의 이전 버전에서는 seq 명령어가 표준 설치되지 않습니다. 대신에 seq 명령어와 거의 같은 동작을 하는  jot 명령어를 사용하기 바랍니다.

    for i in $(jot 10)
    
  • FreeBSD에서는 curl이 표준 설치되지 않습니다. 따라서 대신에 fetch 명령어를 사용합니다.

    fetch "$url"