수업 내용
[연습문제 – test1.sh]
현재 디렉토리 하위의 모든 sh 파일들에 대해 아래와 같이 출력
파일명 : 1_cut.sh 소유자 : itwill 라인수 : 28
# test1.sh
#!/bin/sh
for fname in $(ls -v *.sh)
do
owner=$(ls -l $fname | cut -d" " -f3)
line=$(cat $fname | wc -l)
# echo "파일명 : $fname, 소유자 : $owner 라인수 : $line"
echo "파일명 : $(printf '%-20s' $fname) 소유자 : $(printf '%-10s' $owner) 라인수: $line"
done
[연습문제 – 30_passwd.sh]
패스워드를 입력받고 패스워드가 틀리면 패스워드를 계속 묻는 프로그램 작성
# 30_passwd.sh
#!/bin/sh
echo "패스워드를 입력하세요 : \c"
read passwd
while [ $passwd != 1234 ]
do
echo "잘못된 패스워드입니다"
echo "다시 입력하세요 : \c"
read passwd
done
echo "패스워드 인증 성공"
[eval]
문자들을 명령어로 인식하고 실행시켜주는 명령어
** 문법
eval 대상
ex)
var1=”grep itwill /etc/passwd”
echo $var1
-> grep itwill /etc/passwd
eval $var1
-> itwill:x:1000:1000:itwill:/home/itwill:/bin/bash
[tr]
문자열 치환 및 삭제 명령어
** 문법
tr [옵션] ‘찾을문자열’ ‘바꿀문자열’ < 파일명
또는
cat 파일명 | tr ‘찾을문자열’ ‘바꿀문자열’
** 옵션
-d : 삭제. delete
-s : 반복된 문자열을 한 번만 출력하도록. 중복제거 느낌. 파이썬 set 느낌(집합은 중복 허용 X)
ex)
echo abcba | tr ‘ab’ ‘AB’
-> ABcBA
echo abcba | tr ‘ab’ ‘A’ # sql과는 다르게 삭제는 안되고 치환됨
-> AAcAA
echo abcba | tr -d ‘b’ # 삭제 옵션
-> aca
echo abcba | tr ‘[a-z]’ ‘[A-Z]’ # 정규식도 사용 가능
-> ABCBA
[연습문제 – 32_tr.sh]
파일명을 입력받고 파일의 내용을 모두 대문자로 변경 후 변경 전과 변경 후를 동시 출력 후
변경 후 내용으로 저장할지를 묻고 그에 대한 처리.
# 32_tr.sh
#!/bin/sh
echo -n "파일명을 입력하세요 : "
read fname
if [ -f $fname ]
then
echo "--------변경 전--------"
cat $fname
echo
echo "--------변경 후--------"
cat $fname | tr '[:lower:]' '[:upper:]'
else
echo "파일이 존재하지 않습니다"
exit 1
fi
echo -n "위와같이 파일을 변경할까요?(Y/N) "
read ans
case "$ans" in
[Yy])
cat $fname | tr '[:lower:]' '[:upper:]' > mktemp
mv mktemp $fname
echo "변경이 완료되었습니다"
;;
[Nn])
echo "변경하지 않겠습니다"
;;
*)
echo "잘못된 입력입니다"
echo "종료합니다"
exit 1
;;
esac
exit 0
[sed]
비대화형 편집기. 파일을 열어보지 않고 내용 수정 가능
명령행에서 직접 편집 명령어와 파일을 지정하여 작업한 후 결과를 화면으로 확인.
원본을 건드리지 않아서 저장하려면 따로 tee 또는 redirection 등 필요
** 문법
sed [옵션] ‘명령어’ 파일명
** 명령어(편집 종류)
읽기 : r (외부의 파일을 읽어다가 추가할 때)
출력 : p
삭제 : d
치환 : s
입력 : a, i
** 옵션
-n : 해당패턴 or 실행 결과만을(원하는 라인만) 출력.
-e : 다중 편집
ex)
sed -n ‘/itwill/!p’ test.txt -> itwill이 포함되지 않은 라인들만 출력
sed -n ‘3!p’ test.txt -> 3번째 라인만 빼고 출력
sed -n ‘1,3p’ test.txt -> 1,3번째 라인만 출력
sed ‘1p’ test.txt -> 1번째 라인을 추가 출력(한 번 더 출력)
sed -n ‘/^$/p’ test.txt | wc -l -> 빈 라인의 개수 출력
sed ‘s/itwill/ITWILL/g’ test.txt -> 모든 itwill->ITWILL 변경
sed ‘s/itwill//g’ test.txt -> 모든 itwill 삭제
sed ‘5s/itwill//g test.txt -> 5번째 줄에 있는 itwill 삭제
sed ‘1,3s/^/#/g’ test.txt -> 1~3번 라인 주석 처리
sed ‘1,3s/^#//g’ test.txt -> 1~3번 라인 주석 해제
sed ‘1d’ test2.txt -> 1번째 라인 제거 후 출력
sed ‘/^#/d’ test2.txt -> #으로 시작하는 라인을 제거 후 출력
sed ‘/^#/!d’ test2.txt -> #으로 시작하지 않는 라인 제거 후 출력
sed ‘1,3d’ test2.txt -> 1~3라인 삭제 후 출력
sed ‘/itwill/d’ test2.txt -> itwill 포함된 라인 삭제
sed ‘/^$/d’ test2.txt -> 빈 라인들 삭제
sed ‘3i\asdf’ test.txt -> 3번째 라인을 뒤로 밀고 그 자리에 asdf 추가
sed ‘3a\asdf’ test.txt -> 4번째 라인에 asdf 추가
sed ‘3r test2.txt’ test.txt -> 4번째 라인에 test2.txt의 내용들을 추가
sed -e ‘/^#/d’ test2.txt -e ‘s/itwill/ITWILL/g’ -> #으로 시작하는 라인은 삭제한 뒤, 소문자를 대문자로 치환
[연습문제 – 33_sed1.sh]
현재 디렉토리에 있는 모든 쉘 파일들에 대해 맨 윗줄에 있는 /bin/sh -> /bin/bash로 변경 후 저장
# 33_sed1.sh
#!/bin/sh
echo "bourne shell을 bash shell로 변경"
for fname in $(ls -v *.sh)
do
if [ "$fname" != "$0" ]
then
sed '1,2s/sh/bash/' $fname > ${fname}.imsi
fi
done
echo "변경 완료"
exit 0
[연습문제 – 34_sed2.sh]
현재 디렉토리의 모든 쉘(34번제외)에 대해 맨 마지막에 exit 0으로 끝나지 않는 쉘파일들을 모두 exit 0으로 끝나도록 문서 수정
#!/bin/sh
for fname in $(ls -v *.sh)
do
if [ "$fname" != "$0" ]
then
lastline=$(tail -n 1 "$fname" | tr -d '\n')
if [ "$lastline" != "exit 0" ]
then
echo "-------------------------------"
echo
echo "$fname에 exit 0을 추가합니다"
# echo exit 0 >> "$fname"
sed '$a\exit 0' $fname
echo
echo "exit 0 추가 완료"
else
echo "-------------------------------"
echo "$fname은 이미 exit 0으로 끝납니다"
fi
fi
done
exit 0
#강사님 방법
#!/bin/sh
clear
# env
maindir=/home/itwill/linux_ex/ch9
jobdir=$maindir/jobdir
if [ ! -d $jobdir ]
then
mkdir -p $jobdir
fi
# main
echo "쉘 파일 마지막 라인 exit 0 삽입하기\c"
for i in . . .
do
echo "$i\c"
sleep 1
done
echo
echo "┌────────────────────────┐"
echo "│ 적 용 대 상 │"
echo "└────────────────────────┘"
cd $maindir
for fname in $(ls *.sh)
do
if [ "$fname" != "$0" ]
then
sed '/^$/d' $fname | tail -1 | grep "exit 0" > /dev/null
if [ $? -ne 0 ]
then
sed '$a\exit 0' $fname > ${jobdir}/${fname}
fi
fi
done
ls -v $jobdir
echo
echo "exit 0를 삽입할까요?(Y|N) : \c"
read ans
case $ans in
[Yy]*)
mv ${jobdir}/* ${maindir}
echo "작업 완료"
;;
[Nn]*)
echo "작업 취소"
rm ${jobdir}/*
;;
*)
echo "잘못된 입력입니다"
exit 1
;;
esac