Oracle 26일차

수업 내용

[연습문제 – 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

Leave a Comment