[ Linux / Unix / Shell programming INDEX ]
안녕하세요~~ㅎㅎ
오늘은 반복문 중 for문에 대해서 포스팅을 이어가보도록 하겠습니다.
▼참고
배시 말고 일반 프로그래밍(C, C++ JAVA)에서 for문의 포스팅
[C, C++, Java 등 언어 공통] 반복문 상세설명!(for, do while, 향상된 for문 사용법, 차이점 및 실행 순서)
[C, C++, Java 등 언어 공통] 반복문 상세설명!(for, do while, 향상된 for문 사용법, 차이점 및 실행 순서)
[C언어, C++언어 완전정복 목차 링크!] 문득 그런 날이 있지 않나요? 아무것도 하기 싫은날~~~ㅎㅎㅎㅎㅎ 그렇다고 가만히 있자니 시간이 아깝구 블로그 포스팅을 씁니다. ㅎㅎㅎㅎ 참고로 자바나 C언어나 C++이..
jhnyang.tistory.com
코드에서 빠질 수 없는 구문이라 하면 당연 반복문이겠죠?
특히 자동화 스크립트를 많이 짜는 셸에서는 반복문 활용도가 높습니다.
특정 명령을 규칙에 따라 자동적으로 수행해주는 반복문~ 그 중에서도 오늘은 for문에 대해서 진행할게요!
반복문 for 기본 문법
for 변수 in [범위](리스트 또는 배열, 묶음 등) do 반복할 작업 done
for 변수 in [범위](리스트 또는 배열, 묶음 등)
do
반복할 작업
done
in뒤에 나오는 묶음의 개수만큼 반복이 진행되겠죠?
in뒤에는 그니까 복수가 나오는 데, 쪼개질 수 있는 리스트나, 배열, 명령어의 결과 묶음 등 다양한 것(?)들을 넣어서 활용할 수 있어요 ㅎㅎ
하나씩 순차적으로 빼서 변수에 저장하고 do ~done사이에 있는 작업을 진행합니다.
어떤 디렉터리에 있는 파일들을 하나하나씩 추출해서 반복적으로 특정작업을 하게 할 수도 있고~
특정 횟수만큼 작업을 반복시킬 수도 있고 ~
반복적으로 설정 파일들을 읽어서 실행시킬 수도 있고
활용은 무궁무진합니다 반복문이니까요!! 무엇인들 못하리~
다양한 반복문 문법과 활용법들
▶1. 기본 문법
#!/bin/bash
for var in 1 2 3 4 5
do
echo var value :$var
done
컴마로 1,2,3,4,5 이렇게 하지 않으니 주의~
셸 스크립트는 배열 선언할 때도 원소마다 컴마를 쓰지 않고 띄어쓰기로 구분하죠 ㅎㅎ in뒤에 나오는 값들도 마찬가지입니다. 자 1 2 3 4 5 다섯개의 숫자 리스트가 in뒤에 주어졌어요 var에는 1 2 3 4 5 값이 순차적으로 들어가면서 총 5번 반복됩니다.
기본 문법이라 bash에서도 ksh에서도 대부분의 셸에서 수행 가능해요
하지만 여지껏 포스팅을 보면서 느꼈겠지만, for문 또한 앞으로 나올 문법 중에서는 지원하는 셸도 있지만 지원되지 않는 셸도 있으니 잘 확인하기!
▶2. in 리스트(list)
#case 1
list="1 2 3 4 5"
for var in $list
do
echo var value :$var
done
#case 2
for var2 in "1 2 3 4 5"
do
echo var2 value :$var2
done
분명 같아 보이지만 달라요 ㅎㅎ 주의해야할 점은 in뒤에 따옴표로 저렇게 case 2처럼 넣어주면, 5개가 아니라 하나의 문자열로 간주해버려서 값이 다르게 나옵니다
이유는 문자열조각내기(?) 라는 word spliting기능 때문인데요~! 자세한 것은 "문자열 조각 Word Spliting" 포스팅을 참고해주세요 :)
▶3. 파일 출력하기
for file in /etc/*
do
echo ${file}
done
이렇게 뒤에 와일드카드를 이용한 파일리스트를 in뒤에 지정해줄수도 있어요
그러면 /etc/에 있는 모든 파일들을 하나하나 반복문을 돌면서 접근하게 됩니다.
결과 개수가 너무 많아서 head 명령어를 이용해서 맨 처음 10개 리스트만 출력해줬어요 ㅎㅎ
▶4. 순차적으로 증가하면서 반복 (괄호로 범위 지정)
{START..END}
#!/bin/bash
for var in {1..5}
do
echo var value :$var
done
점이 세개가 아니고 두 개 입니다! 세개로 찍으면 안돼용~
결과는 [1번결과창]과 동일하게 나옵니다. bash는 3.0이전 버전은 지원되지 않습니다.
괄호로 범위지정하는 게 먹히지 않으면 {1..5}를 하나의 문자열로 보고 위와 같이 출력됩니다.
▶5. 일정 간격만큼 증가시키면서 반복 (괄호)
{START..END..INCREMENT}
for var in {1..10..2}
do
echo var value :$var
done
bash 4.0버전부터는 괄호로 범위지정에서 간격까지 지정해줄 수 있습니다. 하나씩 순차가 아니라 2개씩 건너뛸 수 있어요
▶6. 순차적으로 증가하면서 반복 (seq)
seq 명령어는 저 위에 괄호문법이 없었을 시절, 즉 3.0버전 이전에 사용하던 방식입니다.
sequence 시퀀스의 약자예요 ㅎㅎ
만약 너무 옛날 버전이 아니라면, 저 괄호방식을 사용하는게 더 좋고 이건 구식(?)이라 권장되지 않습니다.
어느 환경에서 내가 작업하게 될 지 모르니 알아놓는 것은 당근 좋겠죠!
(유닉스에서는 안되는 경우가 많습니당 )
for var in $(seq 5)
do
echo var value :$var
done
실행 후 출력은 1번 결과창과 동일합니다 ㅎㅎ
$()는 명령 실행을 의미하고 'seq n'는 1부터 n까지 순차적으로 출력해 줘요 ㅎㅎ
for var in `seq 0 5` ; do
echo var value :$var
done
``(역따옴표)는 $()와 같은 역할로 명령을 실행합니다.
seq n은 1부터 n까지였지만, 인자를 두 개를 붙임으로써 시작지점을 지정할 수 있어요 ( seq START END )
시작지점을 0으로 지정해서 5까지 출력해보았습니다
▶7. 일정 간격만큼 증가시키면서 반복 (seq)
for var in `seq 1 2 10`
do
echo var value :$var
done
이렇게 하면 5번 결과창과 동일한 출력을 얻습니다. 1번부터 2씩 건너뛰면서 10이 넘지 않을때까지 수행하라는거죠~ 1, 3, 5, 7 9 요렇게 var에 차례로 대입되겠네요 ㅎㅎ
얘도 역시 UNIX의 AIX 운영체제 ksh에서는 seq 명령어를 찾을 수 없음! 이렇게 나오네요 ㅎㅎ
▶8. in 배열
ary=(1 2 3 4 5)
for var in "${ary[@]}"
do
echo var value :$var
done
ary[@]부문은 ary[*]와 스위칭 가능합니다 (둘 다 똑같은 의미)
IBM 유닉스 운영체제 AIX에서는 배열 선언 방식이 달라요 ㅎㅎ (자세한 건 배열 포스팅에서)
배열 선언 방식 차이는 있을 수 있지만, 이렇게 반복문에서 범위로 넣어서 loop를 돌려줄 수 있다는 거~!
결과창은 1번 결과창과 동일합니다.
▶9. 이중괄호 (( )) double parentheses
for ((i=0; i<5; i++)); do
echo $i
done
그나마 우리가 익숙한 C, JAVA와 비슷한 구문~!
이 이중괄호는 산술연산을 가능하게 확장해줘서 우리가 익숙한 프로그래밍 언어를 사용할 때 처럼 사용가능하게 해줍니다. ㅎㅎ 예전부터 지원했던 기능이 아니기 때문에 최신 버전이 아니거나 오래된 유닉스 서버를 사용하고 계시면 지원안될 수 있습니다.
5보다 작을때까지니까 4까지 출력함!
▶10. 무한루프도 물론 가능
for (( ; ; ))
do
echo "infinite loops, hit CTRL+C to stop"
done
근데 당연히 무한루프가 걸릴 수 있는 가능성이 있다면, 이를 컨트롤해줄 break문과 continue가 있어야겠죠?
셸 프로그래밍에도 해당 명령어가 있습니다 ㅎㅎ
강제종료로 도중에 빠져나오려면 CTRL+C를 누르면 돼요 ㅎㅎ
▶11. break문과 continue!
for file in /etc/*
do
if [ "${file}" == "/etc/shadow" ]; then
echo yes
break
fi
done
3번 예문을 토대로 break문을 넣어봤어요 ㅎㅎ
파일을 검색하다가 만약 "/etc/shadow"파일을 찾으면, yes를 출력하고 반복문을 빠져나오게 처리를 했습니다!
break는 조건을 충족하면 반복문을 빠져나오고,
continue는 조건을 충족하면 그 아래문장을 수행하지 않고 위로 올라가서 다시 한 번 더 반복을 수행해요 ㅎㅎ (나머지는 생략하고 반복조건으로 돌아감)
FILES="$@"
for file in $FILES
do
if [ -f ${file}.bak ]; then
echo "${file}.bak file exists"
continue
fi
cp $file $file.bak
done
만약 파일이 존재하면 그 뒤의 cp명령어를 스킵하고 다음 으로 넘어가요
▶12. 인자로 받을 수도 있어요
i=1
for var
do
echo $var
done
리스트를 인자로 줬기 때문에 in이 없습니다. 생략된거죠 ㅎㅎ
i=1
for var in $*; do
echo $var
done
명시를 해주고 싶으면 인자 전체를 의미하는 위치매개변수 $*나 $@를 넣어주면 돼요
▶13. foreach 문!
#!/bin/csh
foreach i ( 1 2 3 )
echo i value :$i
end
배시나 ksh에서는 아직 지원하지 않지만 csh에서는 지원하는 foreach문도 있습니다.
▶14. 산술연산과 조합하기 좋아요 ( let, expr )등
프로그래밍에서도 조건이 맞으면 반복문을 빠져나오게 조절하기 위해서, 또는 무한루프에 안걸리게 하기 위해서,
변수를 하나씩 증가시켜준다던가 산술연산을 많이쓰죠?
셸 스크립트에서도 이를 가능하게 해주는 let, expr등과 자주 사용됩니다
let 또는 expr은 문자열타입밖에 없는 셸 변수들로 산술연산을 할 수 있도록 도와주는 명령어들이예요
loop_cnt=0
for file in * #현재 디렉터리 모든 파일
do
let loop_cnt+=1 #반복문이 돌때마다 1씩 더함
echo $loop_cnt file: $file
done
▶15. in 뒤에 명령어 실행 결과를 붙여도 된다.
이미 앞의 예제들에서 눈치를 채셨겠지만, in뒤에 리스트들로 명령어 실행을 넣어서 치환할 수 있어요
명령어를 실행시키는 문법으로는 백슬래시랑 $()가 있습니다.
먼저 연습문제로 과일들이 적힌 하나의 파일을 작성해줍시다.
apple banana orange grape
이렇게, fruit_list.txt파일을 하나 만들어서 적어줬어요
for fruit in $(cat fruit_list.txt)
do
echo current fruit: $fruit
done
그리고 스크립트 파일은 위처럼 적은 후 실행시키면,
잘 들어간 것을 확인할 수 있습니다
▶16. 띄어쓰기가 아니라 컴마일때,,
이건 for문 반복문에 오로지 연관이 있다 하긴 어려운데 그냥 조금 더 나아가서 끄적여 보면
보통 설정파일이나 이런 것들을 읽어서 처리할 때가 많은데 , 띄어쓰기만으로 구분이 안되어 있을 수도 있겠죠..
var=a,b,c
for i in ${var//,/ }
do
echo $i
done
"문자열 확장, 치환 포스팅"에서 배웠던, 컴마를 공백으로 변경시켜서 처리할 수도 있습니당
모든지 활용은 자기 하기 나름~
▶17. for문 표준입력, 표준출력 재지향
for name in `seq $line_count`
do
read name
echo "$name"
if [ "$name" = "$FinalName" ]
then
break
fi
done < "$Filename" > "$Savefile"
리다이렉션 <. >를 활용해서, 읽을 파일이랑, 출력 파일을 지정해줄 수 있는거예요
read는 입력을 받는건데, '<'를 이용해서 Filename변수에 저장된 파일로부터 단어를 읽어 name에다가 저장하는걸 반복한다는 코드입니다.중간에 조건문과 break를 통해서 마지막 파일명과 일치하면, 반복문을 빠져나오도록 했네요!
'<'와 반대로, '<'를 사용해서 echo와 같은 출력함수를, 출력파일에다가 남길 수 있도록 입출력 파일들을 지정해주고 있어요 ㅎㅎ
정말 다양한 방법들이 많죠!? ㅎㅎ
좀 알아두면 좋을 표현들을 정리해봤어요!
도움이 되셨다면 가기 전, 덧글, 광고보답 공감 헿~~ 오타지적과 질문 좋아요
오늘도 수고하셨습니다 여러분 다음 포스팅에서 뵈어요!!
지나가다 무릎을 탁! 치고갑니다.
무릎말고 부랄은 안되나요?
이거 스크랩해가도 될까요!? 와 작업하는데 정말 큰 도움이 되었습니다... 구독도 누르고갑니다!
친절한 댓글 감사드립니다~ 출처만 밝혀주시면 스크랩하셔도 됩니다. 도움이 되는 글이라니 정성들여 작성한 보람이 있네요~!! 좋은 하루되세요~
햄찌님 덕분에 많이 알아가네요~! 좋은글 감사드립니다!
도움이 된다니 저야말로 기쁘네요 종종 방문주세요~♡