[vi] 특정 단어부터 끝까지 지우기

프로그래밍/BASH SHELL|2015. 1. 27. 10:05
반응형

sed -e '/END of program/,$d'

반응형

댓글()

간단한 쉘 스크립트의 작성

프로그래밍/BASH SHELL|2015. 1. 27. 10:05
반응형

쉘 프로그래밍으로 형성된 파일이 쉘 스크립트다.

쉘에 접하기에 앞서 우리는 디렉토리 /etc/rc.d에 주목해야 한다. 디렉토리 /etc 아래의 /rc.d/ 에는 많은 파일들이 존재하는데 모두

쉘 스크립트로 짜여진 것이다. 

 

다음의 예제는 가장 일반적인 예제이다.

먼저 다음 예제를 수행하기 위해서는 cat > hello.sh 나 혹은 vi hello.sh와 같은 방버으로 hello.sh를 만드는 방법이 있다.

그 다음으로 우리는 #! /bin/sh와 echo "Hello Word!!" 라는 내용을 다음 예제와 같이 기입해 준다.

 

[예제 1-1] hello.sh

#!/bin/sh

echo "Hello Word!!"

 

와 같이 파일을 생성하고

chmod 700 hello.sh

./hello.sh

와 같이 해주면 출력된 "Hello Word!!" 를 볼 수 있다.

echo는 하나 혹은 그 이상의 문자열이나 변수값 등을 출력해 주는 명령어이다. 위 예제에서는 "Hello Word!!"라는 간단한 문자열을 출력해

보았다. 여기에서 #! <쉘의 위치> 와 같은 형식으로 굳이 이러한 방식으로 하지 않아도 무방하나 가장 일반적인 형식이므로 지켜가며 학습을

하기 바란다.

 

-----------------------------------------------------------------------------------------------

 

다음은 시스템의 환경을 출력해 보고자 할 경우를 나타낸 예제이다.

[예제 1-2] information1.sh

#!/bin/sh

echo " - 시스템 환경 출력 예제 1-1 -"

echo -n "HOSTNAME : "

echo $HOSTNAME

echo -n "USER : "

echo $USER

echo -n "NAME : "

NAME="Linux User Test"

echo $NAME

echo -n "SHELL : "

echo $SHELL

echo -n "pwd : "

pwd

echo -n "ls : "

ls

 

[결과]

 

-----------------------------------------------------------------------------------------------

 

[예제 2] question.sh

#!/bin/sh

echo -n "우리 나라의 영문 국가명은?"

read nation

echo -n "우리 나라의 국보 1호는?"

read kukbo

echo 영문 국가명 : $nation

echo 국보 1호 : $kukbo

 

[결과]

 

read 명령은 키보드로부터 값을 읽어들인 후 그 값을 변수에 저장하고 출력하는 것이다.

 

-----------------------------------------------------------------------------------------------

 

[예제 3] smoker.sh

#!/bin/sh

smoker=10

no_smoker=20

if [ $smoker -lt $no_smoker ]

then

echo "비흡연자가 더 많다."

elif [ $smoker -eq $no_smoker ]

then

echo "흡연자와 비흡연자의 수는 동일하다."

else

"흡연자가 더 많다."

fi

 

[결과]

-if문과 다음에 나오는 '[]' 기호를 붙여서 사용하면 에러가 발생하고 또 기호 '[' 다음에 오는 기호 '$'도 역시 붙여서 기입하면

에러가 발생하므로 이 점을 주의하자.

 

-----------------------------------------------------------------------------------------------

if문

[예제 4] linuxer.sh

#!/bin/sh

vlinuxer=100

Mswindow=5

if [ $vlinuxer -lt $Mswindow ]

then

echo "윈도즈 사용자 수가 더 많다"

elif [ $vlinuxer -eq $Mswindow ]

then

echo "윈도즈 사용자의 수와 리눅서의 수는 동일"

else

echo "리눅스 세계정복!"

fi

 

[결과]

 

-----------------------------------------------------------------------------------------------

case문

[예제 5] vowel.sh

#!/bin/sh

echo -n "아무 것이나 고르시오"

read answer

a="a"

case "$answer" in

a* | e* | i* | o* | u* ) a = "an";;

esac

echo You like $a $answer!

 

[결과]

(한글이 좀 지져분 하지만 밖에나와서 하는중이라 hackerschool linux 이용 -_-ㅋ)

 

-----------------------------------------------------------------------------------------------

 

for 문

[예제 6] for.sh

#!/bin/sh

for A in k o r e a

do

echo $A

done

 

[결과]

 

 

-----------------------------------------------------------------------------------------------

 

[예제 6-1] while.sh

#!bin/sh

loop=1

while [ $loop -lt 10 ]

do

echo "이것은 테스트입니다."

loop=`expr $loop + 1`

done

주의해야할 것은 따옴표(') 가 아닌 숫자 1옆에 ` 이다.

 

[결과]

 

-----------------------------------------------------------------------------------------------

 

[예제 6-2] stupid.sh

#!/bin/sh

while [ 1 ]

do

echo -n "담배가 좋습니까?(예/아니오) : "

read a

if [ x$a = "x예" ]

then

break

else

continue

fi

done

echo "GOOD!"

 

[결과]

 

-----------------------------------------------------------------------------------------------

 

until 문

[예제 7] until.sh

#!/bin/sh

COUNTER=20

until [  $COUNTER -lt 10 ]; do

      echo COUNTER $COUNTER

      let COUNTER-=1

done

 

[결과]


반응형

댓글()

특정 파일 / 디렉토리 바꾸기 (쉘스크립트 포함)

프로그래밍/BASH SHELL|2015. 1. 27. 10:04
반응형

This file is README.txt 

######################################### 
## 
## 스크립트명 : renameto(특정 파일/디렉토리를 바꾸기) 
## 
## 작성자 : 김칠봉 <san2(at)linuxchannel.net> 
## 작성일 : 2003.10.22 pathed for FreeBSD 
##          2002.11.05 add upcase and lowcase, usage to stderr 
##          2002.04.13 patch(sort) 
##          2002.03.29 patch(thanks '단n키') 
##          2002.03.27 add options 
##          2002.03.04 
## 
## 라이센스 : GNU GPL 
## 다운로드 : http://www.linuxchannel.net/devel/renameto/ 
## 
## 
########################################## 

########################################## 
##                                      ## 
## WARNING !!!                          ## 
## 사용자의 사용상 부주의로 인한 피해는 ## 
## 어떠한 경우라고 본 작성자에게 그 책임## 
## 이 없음을 미리 공지합니다.           ## 
##                                      ## 
########################################## 

[기능] 

 - 특정 문자열의 파일을 찾아서 바꿈 
 - 특정 문자열의 디렉토리를 찾아서 바꿈 
 - 바꾸기 전에 view 기능 제공 
 - 특정 디렉토리에서 검색가능 
 - 현재디렉토리, 모든 서브디렉토리, 특정 깊이의 디렉토리 검색 
 - 대소문자 바꾸기 


[사용법] 

# renameto --help 
usage : renameto [options] "/from_string/to_string/" "<target_files|target_directory>" 
  options 
    -R                : include all sub directory (not default) 
    -Rn               : 'n' is sub directory maxdepth number 
                        '-R0' is current directory (same as not given options) 
    -t,-test,--test   : only test view 
    -c,-case,--case   : translate upcase and lowcase 
    -v,-view,--view   : only test view 
    -d,-dir,--dir     : only directory adjust (not files) 
    -h,-help,--help   : help 
  example 
    renameto /html/php/ "*.html" (same as rename command) 
    renameto -R "/ /_/" "* *.mp3" (replace file " " to "_" all sub-directory) 
    renameto -R -test "/ /_/" "* *.mp3" (test view) 
    renameto -R -dir "/ /_/" "/home/xxx/mp3/* *" (replace directory) 
    renameto -R -case "/[A-Z]/[a-z]/" "*" (to lowcase) 
    renameto -R -case "/[e-k]/[E-K]/" "*" (to upcase) 

source download http://ftp.linuxchannel.net/devel/renameto/ 


-R 
  하위의 모든 디렉토리에서 검색 

-R0 
  현재 디렉토리에서만 검색 

-Rn 
  현재디렉토리에서 그다음 n단계 디렉토리까지만 검색, n은 ([0-9]*) 

-R 
  옵션이 없다면 현재디렉토리에서 만 검색 

-d, -dir, --d, --dir 
  파일대신 디렉토리에 적용 
  이 옵션이 없다면 기본적으로 파일을 그 대상으로 함 

-v, -view, --view, -t, -test, --test 
  파일이나 디렉토리를 바꾸지 않고 그냥 찾아서 출력만 함(확인할때) 
  이 옵션이 없다면 매치되는 파일이나 디렉토리를 찾아서 바꿈. 

-c, --case 
  대문자->소문자 or 소문자->대문자 

'/from_string/to_string/' 
  from_string -> to_string 으로 교체 
  공백 문자열이 들어갈 수 있으므로 받드시 전체를 ' 나 "로 묶어줌 
  양자의 구분자는 / 로 구분 

'찾을 디렉토리나 파일 대상' 
  받드시 전체를 ' 나 "로 묶어줌 
  "* *" : 공백 문자열이 들어간 모든 파일이나 디렉토리 대상 
  "*" : 모든 파일이나 디렉토리 대상 
  "*.mp3" : 확장자(?)가 mp3인 모든 파일 
  "*.[hH][tT][mM][lL]" : *.html *.HTML *.Html ... 등과 매치 
  "/home/*.php" : /home 디렉토리를 대상으로 *.php 파일 
  "home/*.php" : 현재 디렉토리에서 상대 경로가 home 인 디렉토리 


[사용예 1] 

/sdb1/mp3 디렉토리 및 그 하위 모든 디렉토리에서 
mp3 파일이나 MP3 파일을 대상으로 
파일이름에 공백(" ")이 들어갈 경우 "_" 로 바꿈 

 먼저 테스트해 봄 

 $ renameto -R --test '/ /_/' '/sdb1/mp3/* *.[mM][pP]3' 
 ... 
 ... 
 $ 

 리스트가 나오면 --test 옵션을 빼고 실행함 

 $ renameto -R '/ /_/' '/sdb1/mp3/* *.[mM][pP]3' 
 ... 
 ... 
 $ 

 -R 
   대상디렉토리(/sdb1/mp3) 및 그 하위의 모든 디렉토리 포함 

 --test 
   단지 테스트만 해봄 

 '/ /_/' 
   공백을 "_"으로 바꾸기 

 '/sdb1/mp3/* *.[mM][pP]3' 
   /sdb1/mp3/ 는 찾을 디렉토리의 시스템 절대경로 
   * *.[mM][pP]3 은 공백 문자열이 들어간 파일의 표현식 


[사용예 2] 

 공백문자 없애기 

 $ renameto '/[ ]//' '*.mp3' 
 또는 
 $ renameto '/ //' '*.mp3' 

 특수문자들 " ( ) * . 없애기 
 $ renameto '/["()*.]//' '*.mp3' 

 특수문자들 [ ] 없애기 
 $ renameto '/[][]//' '*.mp3' 

 확장자 바꾸기 
 $ renameto '/.MP3$/.mp3/' '*.MP3' 

 파일이름 앞에 'My' 문자열 추가하기 
 $ renameto '/^/My/' '*.mp3' 

 파일이름 끝에 'My' 문자열 추가하기 
 $ renameto '/$/My/' '*.mp3' 


[사용예 3] dot(.) 문자 없애기 

 틀린예 : 
 $ renameto '/.//' '*' 

 맞는경우 : 
 $ renameto '/[.]//' '*' 
 또는 
 $ renameto '/.//' '*' 


[사용예 4] 대소문자 바꾸기 

 틀린예 : 
 $ renameto '/[A-Z]/a-z/' '*' (-c 옵션이 빠져있음) 
 $ renameto '/[A-Z]/a-d/' '*' (문자클래스 범위가 맞질않음) 

 대문자 -> 소문자로 바꾸기 
 $ renameto -c '/[A-Z]/a-z/' '*' 
 or 
 $ renameto -c '/[A-Z]/[a-z]/' '*' 

 소문자 -> 대문자 바꾸기 
 $ renameto -c '/[a-z]/A-Z/' '*' 
 or 
 $ renameto -c '/[a-z]/[A-Z]/' '*' 

 특정 클래스(E-K) 알파벳문자 바꾸기 
 $ renameto -c '/[E-K]/e-k/' '*' 
 $ renameto -c '/[e-k]/E-K/' '*' 


[사용예 5] 문자클래스 그룹화 

 모든 대문자 다음에 '_' 문자 추가하기 
 $ renameto '/([A-Z])/1_/' '*' 

 첫번째 공백에 '-' 추가하기 
 $ renameto '/^([^ ]+) /1-/' '*' 


[사용예 6] 종합예제 : mp3 파일 정리 

  $ ls 
  01 aaa.mp3 
  02 bbb (b1).mp3 
  03 ccc Abcd efg.MP3 
  04 ddd bdefgg DDD.mp3 
  05 eee kkk.MP3 
  ... 

  위와 같은 형식을 취하는 여러개의 파일들을 

  artist-[00]-aaa_bbb_ccc.mp3 

  이와같이 형식으로 바꾸려면(대문자->소문자), 

  1. 대문자를 모두 소문자로 바꾸기 
  $ renameto -c '/[A-Z]/a-z/' '*.[mM][pP]3' 

  2. 첫번째 공백을 ']-' 문자로 바꾸기(그룹화 사용) 
  $ renameto '/^([^ ]+) /1]-/' '*.mp3' 

  3. 모든 파일앞에 'artist-[' 문자 추가 
  $ renameto '/^/artist-[' '*' 

  4. 나머지 모든 공백을 '_'로 바꾸기 
  $ renameto '/[ ]/_/' '*' 

  5. 특수문자 괄호 (, )를 없애기(필요하다면) 
  $ renameto '/[()]//' '*' 

  6. 확인 
  $ ls 
  artist-[01]-aaa.mp3 
  artist-[02]-bbb_b1.mp3 
  artist-[03]-ccc_abcd_efg.mp3 
  artist-[04]-ddd_bdefgg_ddd.mp3 
  artist-[05]-eeekkk.mp3 
  ... 


*주의) 
가능한 특수문자는 [와 ]사이에 넣어서 
테스트(-t, --test)를 한 다음에 실행 하세요. 

--------------------------------------------- 


#!/bin/sh 
## 
## "Chilbing, Kim"<san2(at)linuxchannel.net> 
## 2003.10.22 patched for FreeBSD 
## 2002.11.05 add upcase and lowcase, usage to stderr 
## 2002.04.13 patch(sort) 
## 2002.03.29 patch(thanks '단n키') 
## 2002.03.27 add options 
## 2002.03.04 
## 
## http://ftp.linuxchanel.net/devel/renameto/ 
## 
## chmod a+rx renameto 
## cp renameto /usr/local/bin/renameto 

usage() 

echo "${T_MD}usage${T_ME} : renameto [options] "/from_string/to_string/" "<target_files|target_directory>"" >&1 
echo "  ${T_MD}options${T_ME}" >&2 
echo "    -R                : include all sub directory (not default)" >&2 
echo "    -Rn               : 'n' is sub directory maxdepth number" >&2 
echo "                        '-R0' is current directory (same as not given options)" >&2 
echo "    -t,-test,--test   : only test view" >&2 
echo "    -c,-case,--case   : translate upcase and lowcase" >&2 
echo "    -v,-view,--view   : only test view" >&2 
echo "    -d,-dir,--dir     : only directory adjust (not files)" >&2 
echo "    -h,-help,--help   : help" >&2 
echo "  ${T_MD}example${T_ME}" >&2 
echo "    renameto /html/php/ "*.html" (same as rename command)" >&2 
echo "    renameto -R "/ /_/" "* *.mp3" (replace file " " to "_" all sub-directory)" >&2 
echo "    renameto -R -test "/ /_/" "* *.mp3" (test view)" >&2 
echo "    renameto -R -dir "/ /_/" "/home/xxx/mp3/* *" (replace directory)" >&2 
echo "    renameto -R -case "/[A-Z]/[a-z]/" "*" (to lowcase)" >&2 
echo "    renameto -R -case "/[e-k]/[E-K]/" "*" (to upcase)" >&2 
echo "source download ${T_MB}http://ftp.linuxchannel.net/devel/renameto/${T_ME}" >&2 
exit 0 


testing() 

echo "${1}: found '$2'(${T_MG}${4}${T_ME})" 


action() 

echo "${1}: renamed to '${T_MG}${3}${T_ME}'" 
mv "$2" "$3" 


## set color 
## source '/etc/sysconfig/init' 
## 
case $TERM in 
xterm|xterm*|vt220|vt220*|linux) 
T_MG=`echo -e "33[1;32m"` ## bold green 
T_MB=`echo -e "33[1;34m"` ## bold blue 
T_MR=`echo -e "33[1;31m"` ## bold red 
T_MD=`echo -e "33[1;39m"` ## bold white 
T_ME=`echo -e "33[0;39m"` ## normal white 
;; 
default) 
T_MG='' 
T_MB='' 
T_MR='' 
T_MD='' 
T_ME='' 
;; 
esac 

## check_argument number 
## 
[ "$#" -lt "2" ] && usage 

## get options 
## 
for ARGS in $* ; do 
case "$ARGS" in 
-R*) 
  SUB_DIR=$ARGS 
  ;; 
-t*|-v*|--t*|--v*) 
  CMD=testing 
  ;; 
-c*|--c*) 
  CASE=1 
  ;; 
-d*|--d*) 
  TYPE=d ## patch 2002.03.29 
  SORT="-r" 
  ;; 
-h*|--h*) 
  usage 
  ;; 
-*) 
  : ;; 
*) 
  unshift=1 
  ;; 
esac 

[ X"$unshift" = "X" ] && shift 
done 

STRING=$1 
TARGET_FILES=$2 

## recheck argument number 
## 
[ "$#" -lt "2" ] && usage 

## check sub_dir 
## 
if [ X"$SUB_DIR" = "X" ] ; then 
MAXDEPTH="-maxdepth 1" ## current directory search 
else 
MAXDEPTH=`echo "$SUB_DIR" | sed 's/^-R//'` 
if [ `echo "$MAXDEPTH" | egrep "[^0-9]"` ] ; then 
echo "${T_MR}invalid option($SUB_DIR) argument !!!, ex) -R, -R0, -R1, -R2, -R3, ...${T_ME}" >&2 
usage 
fi 

## if $MAXDEPTH is null, then all sub directorys search 
## 
if [ X"$MAXDEPTH" != "X" ] ; then 
maxdepth=$(($MAXDEPTH + 1)) 
MAXDEPTH="-maxdepth $maxdepth" 
fi 
fi 

## check string 
## patch 2002.03.29 
## 
check_string=`echo "$STRING" | egrep "^/([^/]+)/([^/]*)/$"` 
if [ X"$check_string" = "X" ] ; then 
echo "${T_MR}invalid string($STRING) !!!${T_ME}" >&2 
usage 
fi 

## check target_files 
## 
if [ X"$TARGET_FILES" = "X" ] || [ `echo $TARGET_FILES | grep "^-"` ] ; then 
echo "${T_MR}invalid target_file($TARGET_FILES) !!!${T_ME}" >&2 
usage 
fi 

## check find path 
## 
if [ X"`echo $TARGET_FILES | grep /`" != "X" ] ; then 
## same as find_path=`echo "$TARGET_FILES" | sed 's//([^/]*)$//'` 
## 
find_path=${TARGET_FILES%/*} 
find_path=${find_path:-/} ## recheck, patch 2002.03.29 

## same as TARGET_FILES=`echo "$TARGET_FILES" | awk -F"/" '{print($NF)}'` 
## 
TARGET_FILES=${TARGET_FILES##*/} 
fi 

## get from string, to string 
## 
from_string=`echo "$STRING" | awk -F"/" '{print($2)}'` 
to_string=`echo "$STRING" | awk -F"/" '{print($3)}'` 

## check upcase, lowcase translate 
## not good(bad checking T.T) 
## 
if [ X"$CASE" = "X1" ] ; then 
from_tr=`echo "$from_string" | sed 's/[][]//g'` 
to_tr=`echo "$to_string" | sed 's/[][]//g'` 
if [ X$(echo "$from_tr" | tr A-Z a-z) != X$(echo "$to_tr" | tr A-Z a-z) ] ; then 
echo "${T_MR}invalid string($STRING) !!!${T_ME}" >&2 
usage 
fi 
fi 

## lists of files 
## 
files=`find ${find_path:-.} -name "$TARGET_FILES" -type ${TYPE:-f} $MAXDEPTH | sort $SORT 2>/dev/null` 

## good idea 
## 
IFS_ORIG="$IFS" 
IFS=' 


i=0 
for pfile in $files ; do 

## same as file=`basename $pfile` 
## 
file=${pfile##*/} 

## same as path=`echo "$pfile" | sed 's//([^/]*)$//'` 
## 
path=${pfile%/*} 

## if include ${from_string} string in $file, then action 
## 
if [ X$(echo "$file" | grep "$from_string") != "X" ] ; then 
i=$(($i+1)) 
if [ X"$CASE" = "X1" ] ; then 
tofile=`echo "$file" | tr "$from_tr" "$to_tr"` 
else 
## do not sed 's/$AAA/$BBB/g', you must sed "s/$AAA/$BBB/g" 
## 
tofile=`echo "$file" | sed "s${STRING}g"` 
fi 
${CMD:-action} "$i" "$pfile" "$path/$tofile" "$tofile" 
fi 
done 

IFS="$IFS_ORIG" 

exit 0
 


반응형

'프로그래밍 > BASH SHELL' 카테고리의 다른 글

[vi] 특정 단어부터 끝까지 지우기  (0) 2015.01.27
간단한 쉘 스크립트의 작성  (0) 2015.01.27
bash 프롬프트 howto  (0) 2015.01.27
grep 계열 명령어  (0) 2015.01.27
정규표현식  (0) 2015.01.27

댓글()

bash 프롬프트 howto

프로그래밍/BASH SHELL|2015. 1. 27. 10:04
반응형

터미널과 X텀 프롬프트들을 어떻게 생성하고 다룰 것인가에 대하여
논의하며, 또한 사용자명, 현재 작업 디렉토리, 시간 등을 나타내기 위한
표준적인 escape sequence 들을 병합하는 방법도 포함합니다. X텀 제목
표시줄(title bar)을 변경하는 방법, 프롬프트에 정보를 제공하기 위한
외부 함수들의 사용 방법, ANSI 색(color)을 어떻게 사용할 것인가에
대하여 더 많은 제안 들이 제시됩니다.

1. 내용 소개

1.1. 요구 사항

우선, 배쉬가 필요할 것입니다. 대부분의 리눅스 배포본에서 디폴트 버전은
1.14.7 이며(98년 11월, 이 글이 씌어 질 때), 이 버전은 잘 알려져 있으며
또한 신뢰할 만한 쉘입니다. 배쉬는 현재로 버전 2.0 까지 쓰이고
있읍니다:저는 얼마 전 부터 배쉬2.0을 사용해 오고 있읍니다만, 여기에서
제시되는 대부분의 명령어들은 버전 1.14.7 이하에서도 작동할 것입니다.
만약 문제를 인식하게 되면, 그것에 대해서 언급하도록 하겠읍니다.
프롬프트에서 'echo $BASH_VERSION' 이라고 치면 배쉬 버전을 확인할 수
있읍니다. 제 기계의 경우, '2.02.1(1)-release'라고 반응합니다.

쉘 프로그램 경험이 있으면 좋으나, 꼭 필요한 것은 아닙니다: 더 많이
알면, 더 복잡한 프롬프트들을 생성할 수 있을 것입니다. 쉘 프로그램이나
유닉스 도구들에 대한 기초적인 지식은 가지고 있다고 가정합니다. 그러나,
제 자신의 쉘 프로그램 기술이 한계가 있으므로, 고도의 쉘
프로그래머에게는 필요없어 보일 수도 있는 예제나 설명들을 많이 하게 될
것입니다.

1.2. 제안 사항이나 비평 보내기

이 강의는 저에게는 배우는 경험입니다. 어떻게 하면 재미있고 유용한
프롬프트를 만들 수 있는지 많이 알게 되었지만, 이 문서의 내용을
수정하고 향상 시키는 데는 여러분들의 참여가 필요합니다. 이 문서의 가장
최근의 버전은 <http://www.interlog.com/~giles/bashprompt.html> 에서
이용할 수 있읍니다. 이 홈 페이지를 확인하시고, 자유롭게
giles@interlog.com 의 주소로 e-mail 을 주도록 하십시오.

1.3. 칭찬의 글

이 문서를 만드는데는, <http://bash.current.nu/>의 배쉬프롬프트
프로젝트의 작업 으로 부터 많은 것을 차용하였읍니다. 사용된 다른
출처들은 아래와 같읍니다. Eric Lister의 'the xterm Title mini-HOWTO'
<http://sunsite.unc.edu/LDP/HOWTO/mini/Xterm-Title.html>, Keebler의
'Ansi Prompts' <http://www.ncal.verio.com/~keebler/ansi.html>, Stephen
Webb의 'How to make a Bash Prompt Theme'
<http://bash.current.nu/bash/HOWTO.html>, Stumpy의 'X ANSI
Fonts' <http://home.earthlink.net/~us5zahns/enl/ansifont.html>.

또한, 유닉스에 대한 지식에서는 저를 초월하는 Dan, Georgia College &
State University에서 나의 동료 연구자, 과의 몇 번의 토론과 e-mail에서
막대한 도움을 받았읍니다. 그는 몇 번의 아주 우수한 제안과 아이디어를
제시했으며, 결과로 몇 몇의 재미있는 프롬프트를 만들게 되었읍니다.

프롬프트들을 프로그램하는데 유용하게 사용된 세권의 책이 있읍니다.
Jessica Heckman Perry의 Cameron Newham 과 Bill Rosenblatt의 Lowell
Jay Arthur의 (Wiley, 1986. 이 책은 첫 판이고, 네번째 판이 1997년도에
출판되었읍니다.).

2. 배쉬와 배쉬 프롬프트

2.1. 배쉬란 무엇인가

Bourne Shell로 부터 전승된, 배쉬는 GNU 프로젝트인 "Bourne Again
SHell"이며, 대부분의 리눅스 기계에서의 표준적인 명령어 라인
인터페이스입니다. 이것은 상호연결성에서, 그리고 명령어 라인 편집,
완료, 재실행을 지원하는데 탁월합니다. 배쉬는 또한, 형성가능
프롬프트를 지원합니다-많은 사람들이 이점을 인식하고는 있지만 아주 많은
것이 가능하다는 사실을 모르고 있읍니다.

2.2. 배쉬를 잡아 비틀어서 무엇을 하게 할 것인가

대부분의 리눅스 시스템은 단색(일반적으로 회색)의 디폴트 프롬프트를
가지고 있어, 사용자 명, 작업하고있는 기계의 이름, 그리고 현재의 작업
디랙토리등을 표시합니다. 이것이 유용한 정보의 전부이지만, 프롬프트로
훨씬 많은 것을 할 수 있읍니다: 모든 종류의 정보(tty번호, 시간, 날짜,
부하, 사용자의 수, 걸린 시간...)를 표시 할 수 있으며, 프롬프트는 ANSI
색을 사용할 수 있어서 재미있게 보이거나, 어떤 정보 는 돋보이게 할 수
있읍니다. 또한 X텀의 제목 표시줄을 조정할 수 있어서 이들 정보 중 몇
개를 반영할 수 있도록 합니다.

2.3. 고민은 그만하시오

시스템 정보의 자취를 유지하는 것은 종종 유용한 경우가 많읍니다. 몇몇의
사람들 에게 호소력 있게 보이는, 제가 아는 아이디어 중 하나는, 각각의
서로 다른 기계 마다 다른 색깔의 프롬프트를 유지하도록 할 수 있다는 것
입니다. 만약 몇 개의 다른 기계에서 X텀들을 열고 있다거나, 또는 작업
중인 기계가 어느 기계인지 잊어버려서 엉뚱한 파일들을 지워 버리는
경향이 있다면, 이 방법은 현재 작업 중인 기계를 상기 시키는데 있어서
매우 현명한 방법이라는 것을 알게 될 것입니다.

2.4. 첫번째

프롬프트의 생김새는 PS1 쉘 변수로 제어합니다. 명령의 계속은 PS2 쉘
변수에 의해 지정되는데, 이것은 여기서 논의되는 바와 꼭 같은 방법으로
수정할 수 있읍니다- -PS2를 조정하는 것은 정확하게 똑같은 방법이라서,
그렇게 흥미롭지 않으므로 PS1 쉘 변수를 대부분 수정할 것입니다(일반
사용자들은 본적이 없는 PS3, PS4 쉘 변수도 있읍니다-이것들의 사용에
흥미가 있으신 분들은 배쉬 메뉴얼 페이지를 참고 하세요). 프롬프트를
다르게 보이도록 하기 위해서, PS1 쉘 변수를 바꾸면 됩니다. 실험적으로,
현재의 프롬프트에서 직접 PS1 변수를 입력해서 당장 그 결과를 보실 수
있읍니다.(이것은 현재의 쎄션에서만 효력이 있고 로그 아웃하게 되면
사라지게 됩니다). 바뀐 프롬프트를 영구적으로 유지할려고 한다면,
' /.bashrc' 파일을 수정 하여, 그곳에 PS1의 새로운 정의를 첨가하도록
하십시오. 만약 루트의 권한을 갖고 계시다면 '/etc/profile'이라는 파일을
찾아 "PS1=" 라인을 수정할 수 있읍니다. 몇몇의 배포본(적어도 RedHat
5.1)에서는 '/etc/bashrc'파일이 PS1, PS2 쉘 변수를 무효화 시킨다는 점을
주의 하십시오.

시작하기 전에, PS1 변수는 다른 환경 변수들과 마찬가지로 환경변수 기억
장소에 저장되어 있다는 것을 명심해야 합니다. 명령어 라인에서 PS1을
수정하게되면, 당장 프롬프트가 바뀌게 됩니다. 어떠한 변경을 가하기
전에, 또다른 환경변수에 현재의 프롬프트를 저장할 수 있읍니다.

[giles@nikola giles]$ SAVE=$PS1
[giles@nikola giles]$

가장 간단한 프롬프트는 다음과 같이, 하나의 문자로 될 것이죠.

[giles@nikola giles]$ PS1=$
$ ls
bin mail
$

명령어 라인에서 입력함으로써, 기본적인 프롬프트에 대한 실험의 최상의
방법을 설명합니다. 사용자가 입력한 문장은 프롬프트의 바로 뒤에
나타난다는 점을 주목 하십시오: 저는 아래와 같이 사용하기를 더 좋아
합니다.

$PS1="$ "
$ ls
bin mail
$

이것은 프롬프트 뒤에 공백을 두어서, 더 읽기 쉽도록 합니다. 원래의
프롬프트로 복귀하기 위해서는, 단지 저장하였던 변수를 부르기만 하면
됩니다.

$ PS1=$SAVE
[giles@nikola giles]$

2.5. 배쉬 이스케잎 시퀀스(escape sequence)

배쉬 쉘에서는 프롬프트에 삽입하기 위해서 많은 이스케잎 시퀀스가
제공됩니다. 배쉬2.02 메뉴얼 페이지로 부터:

상호적으로 실행할 때, 배쉬는 명령을 받아들일 준비가 되면 기본 프롬프트
PS1을 표시하고, 명령어를 완성하기 위해 더 많은 입력이 요구될 때는
두번째 프롬프트인 PS2를 나타냅니다. 배쉬에서는 이들 프롬프트 변수들이
backslash()와 하나의 문자로 조합된 특수 문자들로 만들어지도록 하며,
그것들은 아래와 같이 해석 됩니다.

a ASCII 종소리 문자(07)
d "요일 달 날짜" 형식의 날짜 표시
(예 : "Tue May 26")
e ASCII의 escape 문자 (033)
h 첫번째 "." 까지의 hostname
H hostname
n 새로운 줄(줄 바꾸기)
r carrage return
s 쉘의 이름, $0 의 basename
(마지막 slash의 다음에 따라오는 부분)
t 24-시간으로 현재 시각, HH:MM:SS(시:분:초) 형식
T 12-시간으로 현재 시각, HH:MM:SS(시:분:초) 형식
@ 12-시간으로 현재 시각, 오전/오후 형식
u 현재 사용자의 username
v bash의 버전(예: 2.00)
V bash의 배포, 버전 패치수준
(예 : 2.00.0)
w 현재 작업 디랙토리
W 현재 작업 디랙토리의 basename
! 현재 명령어의 history 번호
# 현재 명령어의 command 번호
$ 유효한 UID가 0 이면 # 를, 그렇지 않으면 $ 을 표시
nnn 8 진수 nnn에 해당하는 문자
backslash
[ 터미널 조정 sequence를 프롬프트에 끼워 넣기 위해
사용될 수 있는 non-printing 문자의 시작
] non-printing 문자의 끝

떠났던 곳에서 계속해서 :

[giles@nikola giles]$ PS1="u@h W> "
giles@nikola giles> ls
bin mail
giles@nikola giles>

이것은 대부분의 배포본에서의 디폴트와 유사합니다. 저는 약간 다르게
보이기를 원해서 이렇게 바꾸었읍니다:

giles@nikola giles> PS1="[t][u@h:w]$ "
[21:52:01][giles@nikola:~]$ ls
bin mail
[21:52:15][giles@nikola:~]$

3. 외부 명령어들

3.1. PROMPT_COMMAND

배쉬에서는 또 다른 환경 변수 PROMPT_COMMAND가 제공됩니다. 배쉬가
프롬프트를 표시하기 바로 직전에, 정상적인 배쉬 명령어로서, 이 변수의
내용이 실행됩니다.

[21:55:01][giles@nikola:~] PS1="[u@h:w]$ "
[giles@nikola:~] PROMPT_COMMAND="date %H%M"
2155
[giles@nikola:~] d
bin mail
2156
[giles@nikola:~]

위에서 일어난 일을 말씀드리자면, 이스케잎 시퀀스에서 't'를 제외
시켜서, 프 롬프트에 시각이 더 이상 포함되지 않도록 하였읍니다.
그리고나서 'date %H%M' 를 사용하여 제가 더 좋아하는 형식으로 시각을
표시하도록 하였읍니다. 그렇지만 이번에는 프롬프트와는 서로 다른 줄에
나타났읍니다. 배쉬2.0 에서는 배쉬1.14.7에서는 작동하지 않게 됩니다.:
명백히 프롬프트는 다른 식으로 작성되 고, 아래와 같은 방법은 중복된
문장으로 나타납니다.

2156
[giles@nikola:~] PROMPT_COMMAND="echo -n [$(date %H%M)]"
[2156][giles@nikola:~]$
[2156][giles@nikola:~]$ d
bin mail
[2157][giles@nikola:~]$ unset PROMPT_COMMAND
[giles@nikola:~]

화되어, 프롬프트와 함께 모두 한 줄에 나타나게 됩니다. 마지막에서,
'unset' 명령 에 의해 환경 변수 PROMPT_COMMAND가 제거되었읍니다.
명령어 대치를 위해 $() 양식이 사용된 것에 유의하십시오: 즉,

$(date %H%M)

는 "여기에다 'date %H%M' 명령으로 부터의 출력으로 대치하시오" 라는
의미 입니다. 이것은 배쉬2.0 에서 작동합니다. 1.14.7 이전의 몇몇 구
버전의 배쉬 에서는 역인용 부호(backquates)(`date %H%M`)가 필요할 수가
있읍니다. 역인용 부호는 배쉬2.0 에서도 사용 가능하지만, $() 양식을 더
선호 함에 따라 사라져 가고 있으며, $() 양식이 자리를 굳혀 가고
있읍니다. 이 문서에서도 새 양식으로 계속 될 것 입니다. 만약 이전
버전을 사용하고 계시다면, $() 이 나타나는 곳에서 역인용 부호로
대치하면 될 것입니다. 만약, 명령어 대치가 이스케잎 처리되어 있다면
(즉, $(command) ), basckslash('')를 사용하여 양쪽의 역인용 부호를
이스케잎 처리 하십시오(즉, 'command' ).

3.2. 프롬프트에서의 외부 명령어들

프롬프트에서 정상적인 리눅스 명령의 출력 결과도 역시 사용 가능합니다.
너무 많은 것들을 프롬프트에 포함하기를 원하지는 않을 것입니다. 그렇지
않으면 프롬프트가 너무 길어질 테니까요. 또한, 신속히 처리되는 명령어를
사용하기를 원할 것입니다. 왜냐하면, 스크린에 프롬프트가 나타날 때 마다
그명령어들이 수행되어야 하고, 작업을 하는 동안에 프롬프트가 나타나는
것이 성가시게 될 수도 있기 때문입니다.( 이전의 예와 아주 유사한
결과이지만, 배쉬1.14.7에서도 작동합니다)

[21:58:33][giles@nikola:~]$ PS1="[$(date %H%M)][u@h:w]$ "
[2159][giles@nikola:~]$ ls
bin mail
[2200][giles@nikola:~]$

명령어 대치의 달러기호('$') 앞의 backslash에 주의하는 것이 중요합니다.
그것이 없으면 외부 명령어는 정확하게 한번만 수행됩니다: PS1 변수가
읽어 들여질 때 마다. 이 프롬프트의 경우에는, 프롬프트의 길이가 얼마나
되는지 상관 없이 동시에 표시될 것이라는 것을 의미합니다.
backslash('')에 의해 $()의 내용이 쉘 해석으로 부터 보호되어, "date"
명령이 새로운 프롬프트 가 생성될 때 마다 수행됩니다.

리눅스에는 많은 종류의, date, grep, 또는 wc 와 같은 조그마한 유틸리티
프로그램들이 부수되어 있어, 데이타를 처리할 수 있도록 합니다. 만약,
이들 프로그램들의 아주 복잡한 조합을 생성해서 프롬프트 안에 넣고자
하신 다면, 여러분 자신의 쉘 스크립트를 작성한 다음, 프롬프트에서
그것을 불러 들이는 방법이 더 쉬울 수 있읍니다. 적절한 때에 쉘 변수들이
풀어지도록 하기 위해 쉘 스크립트 내에서 자주 이스케잎 시퀀스들이
요구됩니다(위에서 보여진 날짜 명령어와 같이): 이것은 프롬프트 PS1 라인
내에서 한 단계 높은 수준으로 올라 가는 것이며, 쉘 스크립트를 생성하여
회피하는 방법은 아주 훌륭한 아이디어입니다.

프롬프트 내에서 사용되는 조그만 쉘 스크립트 예제가 아래에서
주어집니다.

#!/bin/bash
# lsbytesum - sum the number of bytes in a directory listing
TotalBytes=0
for Bytes in $(ls -l | grep "^-" | cut -c30-41)
do
let TotalBytes=$TotalBytes $Bytes
done
TotalMeg=$(echo -e "scale=3 n$TotalBytes/1048576 nquit" | bc)
echo -n "$TotalMeg"

저는 이것을 때에 따라서 함수로(훨씬 효율적이지만-불행하게도 함수에
대한 자세한 설명은 이 문서의 범위 밖입니다), 또는 경로에 포함되어 있는
' /bin' 디랙토리에 있는 쉘 스크립트로 보관했읍니다. 프롬프트에
사용되어 아래와 같은 결과가 됩니다.

[2158][giles@nikola:~]$ PS1="[u@h:w ($(lsbytesum) Mb)]$ "
[giles@nikola:~ (0 Mb)]$ cd /bin
[giles@nikola:/bin (4.498 Mb)]$

3.3. 프롬프트에서 필요한 그밖의 것들

대부분의 제가 만든 프롬프트에는 시각과 현재 디랙토리의 이름이 포함되어
있다는 것을 알 수 있읍니다. 여기에다가, 소형이지만 효과적인 Dan씨가
만든 프롬프트를 넣고자 합니다.

[giles@nikola:~]$ cur_tty=$(tty | sed -e "s/.*tty(.*)/1/")
[giles@nikola:~]$ echo $cur_tty
p4
[giles@nikola:~]$ PS1="!,$cur_tty,$?$ "
1095,p4,0$

디랙토리 경로를 바꿈에 따라서 프롬프트의 크기가 갑작스럽게 바뀔 수
있기 때문에 Dan씨는 프롬프트에 현재의 디랙토리가 표시되는 것을
좋아하지 않읍니다. 그래서 그는 디랙토리의 자취를 그의 머리속에
기억합니다(또는 "pwd"를 치기도 합니다.) Dan씨는 cash과 tcsh로
유닉스를 익혔기 때문에, 그는 명령어 history를 광범위 하게 사용하고
있으며(우리들의 대부분은 배쉬를 쓴다고 믿기에 그럴 필요가 없지만),
그래서, 그의 프롬프트의 첫번째 항목은 명령어 history 번호입니다.
두번째 항목은 tty의 중요 문자들 입니다("tty"의 출력을 'sed'로
모읍니다). 세번째 항은 마지막 command/pipeline의 exit 값입니다(note
that this is rendered useless by any command executed within the
prompt - you could work around that by capturing it to a variable and
playing it back, though). 마지막으로, "$"은 일반 사용자에게는 달러
기호를 나타내고, 사용자가 루트일 경우에는 해쉬 표시("#") 를
나타냅니다.

3.4. 배쉬 환경과 함수들

앞에서 언급된 바와 같이, PS1, PS2, PS3, PS4 그리고 PROMPT_COMMAND 들은
모두 배쉬 환경으로 저장되어 있읍니다. DOS에 익숙한 분들은 아주 큰
덩어리의 정보를 환경으로 넘기는데에 대하여 두려운 생각을 가질
것입니다. 왜냐하면 DOS의 환경은 조그마했 으며, 잘 확장하지도 않았기
때문입니다. 환경에 넣을 수 있고 넣어야만 하는 것들에 대해서 실제적인
제약이 있을지도 모르지만, 그것들이 뭐가 될지도 모르고, 여기에서 는 DOS
사용자들에게 익숙한 그런 환경보다는 규모에 있어서 아마 몇배나 훨씬 더
큰 것에 대하여 이야기를 하고 있읍니다. 우리의 Dan씨가 말합니다:

"제가 사용하는 쉘에는, 62개의 알리아스와 25개의 함수가 있읍니다.
기계에서 직접 사용할 경우에, 어떤 것이 단독적으로 필요하고 bash에서
손으로 쉽게 씌어질 수 으면, 그것을 쉘 함수로 만든다는 것이 제일 첫번째
규칙입니다(알리아스로 쉽게 표현 할 수 없다는 가정하에서). 만약
메모리에 대해서 걱정하는 사람들이 있다면, 그들은 bash를 사용할 필요가
없읍니다. Bash는 저의 리눅서 기계에서 실행되는 가장 큰 프로그램 중의
하나입니다(Oracle을 제외하고). 때때로 'top'을 실행 시켜서 사용
메모리별로 분류하기 위해 'M'을 눌러 보세요-목록에서 bash가 얼마나
윗쪽에 가까이 있는지 살펴 보세요. 윽, sendmail보다도 더 덩치가 크군요!
그들 더러 가서 ash나 또는 다른 것들을 구하라고 하세요"

아마도 그는 그 작업을 하려고 하는 날에만 콘솔을 사용하지않나
추측합니다:X나 X응용 프로그램을 실행시키면, 배쉬보다 더 큰 것들이 많이
있읍니다. 그렇지만, 아이디어는 동일합니다:환경이라는 것은 사용되어야
하는 것이고, 그것이 차고 넘치는 것은 걱정할 필요가 없읍니다.

제가 이렇게 말할 때(너무 단순화 시켰다는 것에 대해서) 유닉스 구루들로
부터 책망 을 받을 각오를 하지만, 함수들이란 기본적으로 효율성을 위해
환경으로 적재되는 조그만 쉘 스크립트들입니다. Dan씨의 말을 다시
인용합니다:"쉘 함수들은 가능한 만큼 효율화 한것입니다. It is the
approximate equivalent of sourcing a bash/bourne shell script save
that no file I/O need be done as the function is already in memory.
쉘 함수들은 전형적으로, 그것들이 최초의 쉘에서만 필요한지 또는 하부의
쉘에서도 요구되는가에 따라, [.bashrc 또는 .bash_profile]로 부터
적재됩니다. 쉘 스크립트 하나를 실행 시켜서 이것을 대비해 보십시오:
쉘이 분기하여, 자식 프로쎄스가 exec 를 수행하고, potentially 경로가
찾아지고, 커널이 파일을 열고 그 파일을 어떻게 실행할지 결정하기위해
충분한 바이트를 검사하며, 쉘 스크립트인 경우 쉘이 그 스크립트의 이름을
변수로 하여 시작하여야 하며, 그 다음에 파일을 열고, 읽고 그 문장을
수행합니다. 쉘 함수와 비교하여, 문장을 수행하는 것을 빼고는 다른
것들은 불필요한 것으로 간주됩니다."

4. X텀 제목 표시줄의 조작

Non-printing 이스케잎 시퀀스들을 사용하여 흥미있는 프롬프트를 생성할
수 있읍니 다. 이들 이스케잎 시퀀스를 사용하기 위해서는, 그것들을 [ 와
] 로 둘러 쌀 필요 가 있는데, 그렇게 함으로써 배쉬가 프롬프트의 길이를
계산할 때 그것들을 무시하도 록 할 수 있읍니다. 이들 구획 문자들을
빠뜨리게 되면 프롬프트의 실제 길이를 알 수 없게 되기 때문에, 커서가
엉뚱한 곳에 나타나게 됩니다. 또한, 이스케잎 시퀀스들의 앞에는 배쉬버전
2 이전의 경우에는 33[, 그 이후의 버전인 경우에는 33[ 이거나 e[ 이
선행 되어야만 합니다.

콘솔에서, 프롬프트를 써서 X텀의 제목표시줄을 변경하고자 할 경우에는,
프롬프트에 잡동사니들이 나타나게 됩니다. 이것을 피하기 위해서,
프롬프트가 X텀에 있게 될 것이라는 것을 배쉬에게 일러 주기위해 TERM
환경변수를 테스트해 보십시오.

function proml
{
case $TERM in
xterm*)
local TITLEBAR='[33]0;u@h:w07]'
;;
*)
local TITLEBAR=''
;;
esac

PS1="${TITLEBAR}
[$(date %H%M)]
[u@h:w]
$ "
PS2='> '
PS4=' '
}

이것은 ' /.bashrc'에 포함될 수 있는 함수의 하나입니다. 함수의 이름을
불러서 실행할 수 있읍니다. PS1문자열과 마찬가지로, 함수도 환경에
저장되어 있읍니다. PS1문자열이 함수에 의해 한번 설정되면, 'unset
proml' 명령으로 함수를 환경으로 부터 제거할 수 있읍니다. 프롬프트는
X텀에 있는 것에서 콘솔에 있는 것으로 변경할 수 없기 때문에, TERM
변수는 프롬프트가 생성될 때 마다 테스트 되지 않읍 니다. 프롬프트를
정의할 때 연속표시(backslashes'')들을 사용하여, 여러 줄에 걸쳐 그것을
할 수 있읍니다. 이런 방법이 더 읽기 쉽게 해주며, 수정하거나 디버거
시에 유리합니다.

저는 이것을 함수로서 정의하는데, 배쉬프롬프트 패키지(이문서의 후반에서
논의함)가 프롬프트들을 다루는 방법이기 때문입니다:유일한 방법은
아니지만, 잘 작동합니다. 사용하는 프롬프트가 더 복잡해짐에 따라,
그것들을 프롬프트에 타이프하는 것이 더욱 더 성가시게 되므로, 그것들을
텍스트 파일에다 만들어 놓는 것이 더 실용적입 니다. 이 경우에 있어서,
프롬프트에서 테스트하기 위해, "proml"이라는 텍스트 파일에
저장하십시오. 아래와 같이 작업을 할 수 있읍니다.

[giles@nikola:/bin (4.498 Mb)]$ cd -> 프롬프트를 저장하고자 하는
디랙토리로 이동
[giles@nikola:~ (0 Mb)]$ vi proml -> 프롬프트 파일을 작성함
... -> 위에 주어진 내용을 입력함
[giles@nikola:~ (0 Mb)]$ source proml -> 프롬프트 함수를 읽어 들임
[giles@nikola:~ (0 Mb)]$ proml -> 프롬프트 함수를 실행

이 프롬프트를 생성하는 데 있어서 첫번째 스텝은, 우리들이 시작하는 쉘이
X텀인지 아닌지를 테스트합니다:만약 그렇다면, 쉘 변수 (${TITLEBAR})가
정의됩니다. 그것은 적당한 이스케잎 시퀀스들과 X텀 제목표시줄에
<사용자>;@&lt;기계>:<작업 디랙 토리>를 표시하는 u@h:w 로 구성됩니다.
이것은 특별히 최소화된 X텀들에서 유용하고, 더욱 신속하게 터미널을
확인하도록 해 줍니다. 이 프롬프트에 있는 다른 것들은 우리가 이전에
만들었던 것들과 유사할 것입니다.
이런 식으로 X텀 제목표시줄을 조작하는 데 있어 단 하나의 약점은,
제목표시줄 hack를 설정하지 않은 시스템으로 로그인해 들어 갈 때
나타납니다:X텀은 제목 표시줄 hack 가 위치하는 이전 시스템으로 부터의
정보를 계속해서 보여 줄 것입니다.

5. 색

앞에서 언급한 바와 같이, non-printing 이스케잎 시퀀스들은 [33[와
]로 둘러 싸여 있어야만 합니다. 색 이스케잎 시퀀스들의 경우에는,
소문자 m도 같이 넣어야 합니다.

아래와 같은 프롬프트들을 시도해서, 명명된 색깔들이 나타나지 않는다면,
"XTerm*Foreground: BlanchedAlmond" 와 같은 줄이 있는지 살펴 보십시오.
그 줄의 앞쪽에 느낌표('!')를 삽입해서 주석 처리할 수 있읍니다. 물론,
이 작업은 사용하는 터미널 에뮬레이터의 종류에 따라 달라 집니다. 이것이
터미널의 전경 색깔을 무효화 할 수 있는 가장 가능성이 있는 곳입니다.

프롬프트에 파란색 텍스트를 포함하기 위해 :

PS1="[33[34m][$(date %H%M)][u@h:w]$ "

이 프롬프트의 문제점은, 34번 색 코드로 시작하는 파란색깔이 통상적인
회색으로 되돌아 가지 않아서, 프롬프트 뒤에 써 넣는 어떤 종류의
텍스트라도 프롬프트와 같은 색을 가지게 된다는 것입니다. 이것은 어두운
파란색이라서, 강조 코드가 약간은 도움이 될 수 있읍니다.

PS1="[33[1;34m][$(date %H%M)][u@h:w]$[33[0;37m] "

이제는 밝은 파란색으로 되며, 대부분의 사람들이 바라는 회색으로 되돌아
가서 끝 나게 됩니다.

주의 : 다음과 같은 점을 지적해 두고자 합니다. 만약, X텀을 사용하면서,
터미널의 색깔에 대해 "xterm -bg midnightblue -fg yellow" 과 같은식으로
설정해 놓으셨다면, 위에서 기술한 바와 같이 색깔을 되돌리는 작업이
여러분들이 설정한 "-fg"을 무효화 시킨다는 것입니다. 저는 이문제를
해결하지 못했으며, 여러분들이 해법을 발견하게 되면 저에게 일러 주시기
바랍니다. 여러분들이 밝은 색의 배경을 사용하고 계신다면, 위에서 사용된
회색 텍스트는 읽기가 곤란할 것입니다. 또한, X텀에서 밝은 배경을
사용하면서, 콘솔과 X텀 양쪽에서 프롬프트를 사용하기를 원하시면 제목
표시줄 절에 서 보인 바와 같이 "case $TERM in ..." 로써 색 설정에
대해서 약간의 조정을 할 필요가 있읍니다.

아래에 색상표가 주어집니다:

Black 0;30 Dark Gray 1;30
Blue 0;34 Light Blue 1;34
Green 0;32 Light Green 1;32
Cyan 0;36 Light Cyan 1;36
Red 0;31 Light Red 1;31
Purple 0;35 Light Purple 1;35
Brown 0;33 Yellow 1;33
Light Gray 0;37 White 1;37

배경색도 또한 설정할 수 있는데, 파란 배경에 대해서는 44, 빨간색 배경에
대해서는 41, 등을 사용할 수가 있읍니다. 배경색에 대해서는 강조 색은
없읍니다. 파란색 배경에 밝은 빨간색 텍스트와 같이 조합을 해서도
사용할 수있읍니다: [33[44;1;31m], 그렇지만, 따로 따로 색깔을
설정하는 것이 더 잘 작동하는 것 같읍니다(즉,
[33[44m][33[1;31m]). 다른 코드들도 포함하여 사용할 수 있는데,
4:밑줄, 5:깜박거림, 7:반전 그리고 8:숨김 등이 있읍니다.

프롬프트 패키지(제가 수정을 하여, 원문을 보기위해 요구되는 특별한 X텀
폰트들 을 사용하기 보다는 표준적인 콘솔에서 더 잘 작동하도록
만들었읍니다)에 있는 "elite2"라고 이름 붙인 프롬프트에 근거하여,
아래의 프롬프트는 제가 아주 많이 사용하는 것입니다.

function elite
{

local GRAY="[33[1;30m]"
local LIGHT_GRAY="[33[0;37m]"
local CYAN="[33[0;36m]"
local LIGHT_CYAN="[33[1;36m]"

case $TERM in
xterm*)
local TITLEBAR='[33]0;u@h:w07]'
;;
*)
local TITLEBAR=""
;;
esac

local GRAD1=$(tty|cut -d/ -f3)
PS1="$TITLEBAR
$GRAY-$CYAN-$LIGHT_CYAN(
$CYANu$GRAY@$CYANh
$LIGHT_CYAN)$CYAN-$LIGHT_CYAN(
$CYAN#$GRAY/$CYAN$GRAD1
$LIGHT_CYAN)$CYAN-$LIGHT_CYAN(
$CYAN$(date %H%M)$GRAY/$CYAN$(date %d-%b-%y)
$LIGHT_CYAN)$CYAN-$GRAY-
$LIGHT_GRAYn
$GRAY-$CYAN-$LIGHT_CYAN(
$CYAN$$GRAY:$CYANw
$LIGHT_CYAN)$CYAN-$GRAY-$LIGHT_GRAY "
PS2="$LIGHT_CYAN-$CYAN-$GRAY-$LIGHT_GRAY "
}

색깔들을 읽기 쉬운 이름으로 임시 쉘 변수로 정의 하였읍니다. 이렇게
하면, 작업 하기에 편리합니다. "GRAD1"변수가 사용되어, 사용하는
터미널의 종류를 결정합니다. X텀에서 작업을 하는지 결정하기 위해
테스트한 것과 마찬가지로, 단지 한번만 실행될 필요가 있읍니다. 색깔을
제외하면, 아래와 같은 프롬프트를 보시게 됩니다.

--(giles@nikola)-(75/ttyp7)-(1908/12-Oct-98)--
--($:~/tmp)--

6. 배쉬 프롬프트 패키지

6.1. 입수 가능한 곳

배쉬 프롬프트 패키지는 <http://bash.current.nu> 에서 구할 수있으며,
이 작업은 Rob Current(aka BadLandZ) 씨의 조정하에 몇몇 사람들이
참여하여 이루 어진 것입니다. 이 패키지는 예전 부터 베타 버전이지만,
다중 프롬프트(theme)를 사용할 수 있도록 하는 아주 간단한 방법을
제공하여, 로그인 쉘과 하부쉘에서 프롬프트를 설정할 수 있게 합니다(즉,
PS1 문자열을 ' /.bash_profile'과 ' /.bashrc' 파일에 저장 함으로써).
대부분의 테마(theme)들은 확장 VGA 문자 세트들을 사용하기 때문에, VGA
폰트(대부분의 시스템에서 디폴트가 아님)에 익숙하지 않으신 분들에게는
좋지 않게 보입니다.

6.2. X텀 폰트 바꾸기

배쉬 프롬프트 패키지에 있는 가장 매력적인 프롬프트 몇개를 사용히기
위해서는, 프롬프트에 쓰일 문자세트들을 지원하는 폰트를 구해서 설치할
필요가 있읍니다. 이것들은 "VGA 폰트"라고 하지만, 리눅스에 일반적으로
적재되는 폰트들-확실히 다른 문자 세트를 지원하기는 하지만-과의 차이가
명확하지는 않다고 봅니다. 표준 X텀 폰트들은, 많은 종류의 강조 문자들을
포함해서, 확장 알파베트를 지원합니다. VGA 폰트에서는, 이러한 것들은
그래픽 문자들-블록, 점, 선들-로 대치됩니다. 이것을 더 자세히 설명할 수
있는 분이 계시다면, e-메일을 보내 주시기 바라며, 여기에 포함 시키도록
하겠읍니다.

이들 폰트를 구해서 설치하는 것은 약간 복잡한 과정을 거칩니다. 우선, 그
폰트(들) 을 복구합니다. 다음으로, 그것들이 .pcf 또는 .pcf.gz 형식의
파일인지 확인합니다. 만약, 그것들이 .bdf 파일이면, "bdftopcf"명령을
조사합니다(즉, 맨 페이지를 읽어 봅니다). 그리고 .pcf 또는 .pcf.gz
파일들을 '/usr/X11R6/lib/X11/fonts/misc' (RedHat5.1 과 Slackware3.4 의
경우에는 이 디랙토리가 올바른 디랙토리이지만, 그 밖의 배포본에서는
다른 디랙토리가 될 수도 있읍니다) 디랙토리에 옮기세요. "cd" 명령으로
그 디랙토리로 바꾼 다음에, "mkfontdir" 명령을 실행 시킵니다. 그 다음에
"xset fp rehash" 를 실행합니다. 때때로, 같은 디랙토리에 있는
'fonts.alias' 파일 을 편집해서, 그 폰트에 해당하는 더 짧은 알리아스
이름을 만드는 것도 훌륭한 아이디어입니다.

새로운 폰트들을 사용하기 위해서는, 여러분의 X텀에 맞는 적당한
명령어로써 선택된 옵션들을 포함해서 X텀 프로그램을 시작하면 되는데,
이러한 작업에 대해서는 맨 페이지나 또는 명령어 줄에서 "--help"를
사용해서 알아 낼 수 있읍니다. 아래의 예는 대중적으로 많이 쓰이는 용어
입니다:

xterm -font <fontname>

또는

xrerm -fn <fontname> -fb <fontname-bold>
Eterm -f <fontname>
rxvt -fn <fontname>

VGA 폰트들은 <http://hoome.earthlink.net/~us5zahns/enl/ansifont.htm>
의 'Stumpy's ANSI Fonts' 페이지에서 구할 수 있읍니다(제가 이 글을
쓰면서 많은 부분을 참조한 페이지임).

7. 다른 프롬프트 불러 들이기

7.1. 조금 후에, 다른 프롬프트 불러 들이기

이 HOWTO 문서에서, PS1 환경 변수들을 어떻게 만들며, 또 이들 PS1과 PS2
문자열들을 어떻게 함수에 합병해 넣어서, ' /.bashrc' 나 프롬프트
페키지의 테마로써 실행될 수 있는 지에 대하여 설명하였읍니다.

배쉬 프롬프트 페키지를 사용할 경우에, 'bashprompt -i'라고 입력하여
사용 가능한 테마들의 목록을 볼 수 있읍니다. 앞으로의 로그인
쉘(여러분들의 X텀 설정에 따라 다르기는 하지만, 주로 콘솔, 뿐만 아니라,
텔넷이나 X텀)에서 프롬프트를 설정하기 위해서는, 그러면, 요청된 테마가
시작될 때, 그것을 부를 수 있도록, 배쉬프롬프트는 앞으로의 하부
쉘(대개, X텀, rxvt, 등)에서의 프롬프트를 설정하기위해서는, 수정하여,
기동할 때, 적절한 테마를 부를 수 있도록 합니다.

7.2. 지금 즉시, 다른 프롬프트 불러 들이기

현재의 터미널에서(위에서 제시된 예인 'elite'함수를 사용해서)
프롬프트를 바꿀 수 있는데, 'source elite'라고 친 다음에
'elite'('elite'함수 파일이 작업 디랙토리에 있다고 가정)를 입력하면
됩니다. 이렇게 하는 것은 약간 성가신 작업이며, 여러분의 환경 공간에
여분의 함수(elite)를 남겨 놓는 것이 됩니다-환경에서 그것을 깨끗이
지우고 싶으시면, 역시, 'unset elite'라고 입력하시면 됩니다. 이렇게
하는 것이 조그만 쉘 스크립트에 대해서는 이상적인 방법 같이 보이지만,
여기에서는 스크립트는 작동하지 않읍니다. 왜냐하면, 스크립트로는 현재
쉘의 환경을 변경할 수 없기 때문입니다:스크립트는 하부 쉘의 환경만 바꿀
수 있읍니다. 스크립트가 정지하는 순간에, 하부 쉘은 사라지게 되고, 그
스크립트에 의해서 변경 된 하부 쉘의 환경도 사라지게 됩니다. 현재 쉘의
환경 변수들을 바꿀 수 있는 것은 환경 함수들 뿐입니다. 배쉬프롬프트
패키지에 의해서, "callbashprompt"라고 불리는 함수가 환경에 추가되며,
그리고, while they don't document it, 배쉬 진행 중에, 그 함수가
불리어져, 어떤 배쉬 프롬프트라도 적재 할 수 있읍니다. 그 함수는
테마가 설치된 디랙토리(여러분이 부를려고 하는 테마는 여기에 있어야
합니다)를 살펴 보고, 요청된 함수를 소스화 해서, 그 함수를 적재하고,
그리고나서 그함수를 내리게 되어, 환경을 정돈된 상태로 유지합니다.
"callbashprompt"는 이렇게 사용되기로 의도된 것도 아니며, 오류 검사도
없지만, 이 점만 명심한다면, 잘 작동합니다.

8. 프롬프트 색을 동적으로 불러 들이기

8.1. 예 "Proof of Concept"

아래의 예는 흥미로운 프롬프트라기 보다는 "proof of concept"
입니다:동적으로 프롬프트 안의 색깔을 바꾸는 것입니다. 이 예에서는,
시스템의 부하에 따라서, 호스트 이름의 색깔을 바꾸게 됩니다(경고 로서).

#!/bin/bash
# "hostloadcolour" - 17 October 98, by Giles
#
# The idea here is to change the colour of the host name in the prompt,
# depending on a threshold load value.

# THRESHOLD_LOAD is the value of the one minute load (multiplied
# by one hundred) at which you want
# the prompt to change from COLOUR_LOW to COLOUR_HIGH
THRESHOLD_LOAD=200
COLOUR_LOW='1;34'
# light blue
COLOUR_HIGH='1;31'
# light red

function prompt_command {
ONE=$(uptime | sed -e "s/.*load average: (.*...), (.*...), (.*...)/1/" -e "s/ //g")
# Apparently, "scale" in bc doesn't apply to multiplication, but does
# apply to division.
ONEHUNDRED=$(echo -e "scale=0 n $ONE/0.01 nquit n" | bc)
if [ $ONEHUNDRED -gt $THRESHOLD_LOAD ]
then
HOST_COLOUR=$COLOUR_HIGH
# Light Red
else
HOST_COLOUR=$COLOUR_LOW
# Light Blue
fi
}

function hostloadcolour {

PROMPT_COMMAND=prompt_command
PS1="[$(date %H%M)][u@[33[$(echo -n $HOST_COLOUR)m]h[33[0;37m]:w]$ "
}

여러분이 선호하시는 편집기를 이용해서, 이 파일을 "hostloadcolour"라는
이름으로 저장하십시오. 만약, 배쉬프롬프트 패키지를 이미 설치하셨다면,
이 파일은 테마의 하나로서 작동할 것입니다. 배쉬프롬프트를 설치하지
않았다면, 'source hostloadcolour'라고 치고나서, 어느 쪽이든지,
"prompt_command"는 여러분들의 환경에서 함수들 중 하나가 됩니다. 위
코드를 잘 살펴 보시면, 색깔들($COLOUR_HIGH 와 $COLOUR_LOW)이 부분적인
색상 코드(즉, "[33[1;34m]" 대신에 "1;34")로 만 설정되어 있다는
것을 아시게 될 것입니다. 이 방법을 저는 더 선호합니다. 저는 완성된
코드로 작동하게 할 수가 없었는데, 이 문제를 다룰 수 있으면 저에게 일러
주십시오.

9. 예제 프롬프트들

9.1. "Lightweight" 프롬프트

function proml {
local BLUE="[33[0;34m]"
local RED="[33[0;31m]"
local LIGHT_RED="[33[1;31m]"
local WHITE="[33[1;37m]"
local LIGHT_GRAY="[33[0;37m]"
case $TERM in
xterm*)
TITLEBAR='[33]0;u@h:w07]'
;;
*)
TITLEBAR=""
;;
esac

PS1="${TITLEBAR}
$BLUE[$RED$(date %H%M)$BLUE]
$BLUE[$LIGHT_REDu@h:w$BLUE]
$WHITE$$LIGHT_GRAY "
PS2='> '
PS4=' '
}

9.2. 배쉬프롬프트 테마에서의 'elite'

이 프롬프트는 VGA 폰트가 필요하다는 점에 유의 하십시오.

# Created by KrON from windowmaker on IRC
# Changed by Spidey 08/06
function elite {
PS1="[33[31m]332304[33[34m]([33[31m]u[33[34m]@[33[31m]h
[33[34m])[33[31m]-[33[34m]([33[31m]$(date %I:%M%P)
[33[34m]-:-[33[31m]$(date %m)[33[34m33[31m]/$(date %d)
[33[34m])[33[31m]304-[33[34m]371[33[31m]-371371
[33[34m]372n[33[31m]300304[33[34m]([33[31m]W[33[34m])
[33[31m]304371[33[34m]372[33[00m]"
PS2="> "
}

9.3. "Power User" 프롬프트

저는 실제로 이 프롬프트를 사용하고 있지만, PII 400, single-user
시스템에서 프롬프트가 나타나는 데는 감지할 수있을 정도의 지연이
나타나므로, PII 100 또는 다른 muti-user 시스템에는 사용하기를 권장하지
않읍니다. 실제적인 프롬프트로 쓰기 위해서 보다는, 아이디어를 얻기
위해 잘 살펴 보시기 바랍니다.

#!/bin/bash
#----------------------------------------------------------------------
# POWER USER PROMPT "pprom2"
#----------------------------------------------------------------------
#
# Created August 98, Last Modified 9 November 98 by Giles
#
# Problem: when load is going down, it says "1.35down-.08", get rid
# of the negative
# - limit the length of the $PWD to 30 chars - right-truncate if
# it exceeds that

function prompt_command
{
# Create TotalMeg variable: sum of visible file sizes in current directory
local TotalBytes=0
for Bytes in $(ls -l | grep "^-" | cut -c30-41)
do
let TotalBytes=$TotalBytes $Bytes
done
TotalMeg=$(echo -e "scale=3 nx=$TotalBytes/1048576n if (x<1) {print "0"} n print x nquit" | bc)

# This is used to calculate the differential in load values
# provided by the "uptime" command. "uptime" gives load
# averages at 1, 5, and 15 minute marks.
#
local one=$(uptime | sed -e "s/.*load average: (.*...), (.*...), (.*...)/1/" -e "s/ //g")
local five=$(uptime | sed -e "s/.*load average: (.*...), (.*...), (.*...).*/2/" -e "s/ //g")
local diff1_5=$(echo -e "scale = scale ($one) nx=$one - $fiven if (x>0) {print "up"} else {print "down"}n print x nquit n" | bc)
loaddiff="$(echo -n "${one}${diff1_5}")"

# Count visible files:
let files=$(ls -l | grep "^-" | wc -l | tr -d " ")
let hiddenfiles=$(ls -l -d .* | grep "^-" | wc -l | tr -d " ")
let executables=$(ls -l | grep ^-..x | wc -l | tr -d " ")
let directories=$(ls -l | grep "^d" | wc -l | tr -d " ")
let hiddendirectories=$(ls -l -d .* | grep "^d" | wc -l | tr -d " ")-2
let linktemp=$(ls -l | grep "^l" | wc -l | tr -d " ")
if [ "$linktemp" -eq "0" ]
then
links=""
else
links=" ${linktemp}l"
fi
unset linktemp
let devicetemp=$(ls -l | grep "^[bc]" | wc -l | tr -d " ")
if [ "$devicetemp" -eq "0" ]
then
devices=""
else
devices=" ${devicetemp}bc"
fi
unset devicetemp

}

PROMPT_COMMAND=prompt_command

function pprom2 {

local BLUE="[33[0;34m]"
local LIGHT_GRAY="[33[0;37m]"
local LIGHT_GREEN="[33[1;32m]"
local LIGHT_BLUE="[33[1;34m]"
local LIGHT_CYAN="[33[1;36m]"
local YELLOW="[33[1;33m]"
local WHITE="[33[1;37m]"
local RED="[33[0;31m]"

case $TERM in
xterm*)
TITLEBAR='[33]0;u@h:w07]'
;;
*)
TITLEBAR=""
;;
esac

PS1="$TITLEBAR
$BLUE[$RED$(date %H%M)$BLUE]
$BLUE[$REDu@h$BLUE]
$BLUE[
$LIGHT_GRAY${files}.${hiddenfiles}-
$LIGHT_GREEN${executables}x 
$LIGHT_GRAY(${TotalMeg}Mb) 
$LIGHT_BLUE${directories}.
${hiddendirectories}d
$LIGHT_CYAN${links}
$YELLOW${devices}
$BLUE]
$BLUE[${WHITE}${loaddiff}$BLUE]
$BLUE[
$WHITE$(ps ax | wc -l | sed -e "s: ::g")proc
$BLUE]
n
$BLUE[$RED$PWD$BLUE]
$WHITE$

$LIGHT_GRAY "
PS2='> '
PS4=' '
}

9.4. 터미널의 폭 프롬프트

한 친구가 불평을 했는데, 프롬프트 안에 $PWD 명령이 있어서 계속 길이가
바뀌는 그런 프롬프트를 좋아 하지않는다고 했읍니다. 그래서, 여러분들의
터미널의 폭에 꼭 맞도록 길이를 조정할 수 있는 프롬프트를 작성
하였읍니다.

#!/bin/bash

# termwide prompt
# by Giles - created 2 November 98
# last modified 9 November 98
#
# The idea here is to have the upper line of this two line prompt
# always be the width of your term. Do this by calculating the
# width of the text elements, and putting in fill as appropriate
# or right-truncating $PWD.
#
# - needs a lot of refinement, but it works
# - host doesn't need to be figured out every time: that's a
# constant
# - what about username? could change?
# - text vars generated by prompt_command can't be locals,
# because they have to go to PS1.

function prompt_command {

TERMWIDTH=${COLUMNS}

# Calculate the width of the prompt:

hostnam=$(echo -n $HOSTNAME | sed -e "s/[.].*//")
let hostsize=$(echo -n $hostnam | wc -c | tr -d " ")
# "whoami" and "pwd" include a trailing newline
usernam=$(whoami)
let usersize=$(echo -n $usernam | wc -c | tr -d " ")
newPWD="${PWD}"
let pwdsize=$(echo -n ${newPWD} | wc -c | tr -d " ")
# Add all the accessories below ...
let promptsize=$(echo -n "--(${usernam}@${hostnam})---(${PWD})--" 
| wc -c | tr -d " ")
let fillsize=${TERMWIDTH}-${promptsize}
fill=""
while [ "$fillsize" -gt "0" ]
do
fill="${fill}-"
let fillsize=${fillsize}-1
done

if [ "$fillsize" -lt "0" ]
then
let cut=((${fillsize})*(-1)) 3
sedvar=""
while [ "$cut" -gt "0" ]
do
sedvar="${sedvar}."
let cut=${cut}-1
done
newPWD="...$(echo -n $PWD | sed -e "s/(^${sedvar})(.*)/2/")"
fi
}

PROMPT_COMMAND=prompt_command

function termwide {

local GRAY="[33[1;30m]"
local LIGHT_GRAY="[33[0;37m]"
local WHITE="[33[1;37m]"

local LIGHT_BLUE="[33[1;34m]"
local YELLOW="[33[1;33m]"

case $TERM in
xterm*)
TITLEBAR='[33]0;u@h:w07]'
;;
*)
TITLEBAR=""
;;
esac

PS1="$TITLEBAR
$YELLOW-$LIGHT_BLUE-(
$YELLOW${usernam}$LIGHT_BLUE@$YELLOW${hostnam}
${LIGHT_BLUE})-${YELLOW}-${fill}${LIGHT_BLUE}-(
$YELLOW${newPWD}
$LIGHT_BLUE)-$YELLOW-
n
$YELLOW-$LIGHT_BLUE-(
$YELLOW$(date %H%M)$LIGHT_BLUE:$YELLOW$(date " %a,%d %b %y")
$LIGHT_BLUE:$WHITE$$LIGHT_BLUE)-
$YELLOW-
$LIGHT_GRAY "

PS2="$LIGHT_BLUE-$YELLOW-$YELLOW-$LIGHT_GRAY "




반응형

'프로그래밍 > BASH SHELL' 카테고리의 다른 글

간단한 쉘 스크립트의 작성  (0) 2015.01.27
특정 파일 / 디렉토리 바꾸기 (쉘스크립트 포함)  (0) 2015.01.27
grep 계열 명령어  (0) 2015.01.27
정규표현식  (0) 2015.01.27
쉘 문법  (0) 2015.01.27

댓글()

grep 계열 명령어

프로그래밍/BASH SHELL|2015. 1. 27. 10:03
반응형
제3장 grep 계열 명령어

3.1 grep 명령어

3.1.1 grep의 의미

grep : 파일 전체를 뒤져 정규표현식에 대응하는 모든 행들을 출력한다. 
egrep : grep의 확장판으로, 추가 정규표현식 메타문자들을 지원한다. 
fgrep : fixed grep 이나 fast grep으로 불리며, 모든 문자를 문자 그래도 취급한다. 즉, 정         규표현식의 메타문자도 일반 문자로 취급한다.

3.1.2 grep의 동작 방법

grep에서 사용하는 정규표현식 메타문자
메타문자
기    능
사용 예
사용 예 설명
^
행의 시작 지시자
'^love'
love로 시작하는 모든 행과 대응
$
행의 끝 지시자
'love$'
love로 끝나는 모든 행과 대응
.
하나의 문자와 대응
'l..e'
l 다음에 두 글자가 나오고 e로 끝나는 문자열을 포함하는 행과 대응
*
선행문자와 같은 문자의 0개 혹은 임의개수와 대응
' *love'
0개 혹은 임의 개수의 공백 문자 후에 love로 끝나는 문자열을 포함한 행과 대응
[]
[] 사이의 문자 집합중 하나와 대응
'[Ll]ove'
love나 Love를 포함하는 행과 대응
[^ ]
문자집합에 속하지 않는 한 문자와 대응
'[^A-K]love'
A와 K 사이의 범위에 포함되지 않는 한 문자와 ove가 붙어있는 문자열과 대응
<
단어의 시작 지시자
'<love'
love로 시작하는 단어를 포함하는 행과 대응(vi,grep에서 지원)
>
단어의 끝 지시자
'love>'
love로 끝나는 단어를 포함하는 행과 대응
(vi,grep에서 지원)
(..)
다음 사용을 위해 태그를 붙인다.
'(lov)ing'
지정된 부분을 태크1에 저장한다. 나중에 태그값을 참고하려면 1을 쓴다. 맨 왼쪽부터 시작해 태그를 9개가지 쓸 수 있다. 왼쪽 예에서는 lov가 레지스터1에 저장되고 나중에 1로 참고할 수 있다.
x{m}
문자 x를 m번 반복한다.
'o{5}'
문자 o가 5회 연속적으로 나오는 모든 행과 대응
x{m,}
적어도 m번 반복한다.
'o{5,}'
문자 o가 최소한 5회 반복되는 모든 행과 대응
x{m,n}
m회 이상 n회 이하 반복한다.
o{5,10}'
문자 o가 5회에서 10회 사이의 횟수로 연속적으로 나타나는 문자열과 대응

grep의 옵션
옵션
동작 설명
-b
검색 결과의 각 행 앞에 검색된 위치의 블록 번호를 표시한다. 검색 내용이 디스크의 어디쯤 있는지 위치를 알아내는데 유용하다.
-c
검색 결과를 출력하는 대신, 찾아낸 행의 총수를 출력한다.
-h
파일 이름을 출력하지 않는다.
-i
대소문자를 구분 하지 않는다.(대문자와 소문자를 동일하게 취급).
-l
패턴이 존재하는 파일의 이름만 출력한다.(개행문자로 구분)
-n
파일 내에서 행 번호를 함께 출력한다.
-s
에러 메시지 외에는 출력하지 않는다. 종료상태를 검사할 때 유용하게 쓸 수 있다.
-v
패턴이 존재하지 않는 행만 출력한다.
-w
패턴 표현식을 하나의 단어로 취급하여 검색한다.

 # grep -n '^jack:' /etc/passwd 
(/etc/passwd 파일에서 jack을 찾는다. jack이 행의 맨 앞에 있으면 행 번호를 화면으로 출력한다.)

3.1.3 grep과 종료 상태 
grep은 파일 검색의 성공 여부를 종료 상태값으로 되돌려준다. 
패턴을 찾으면 0, 패턴을 찾을 수 없으면 1, 팡리이 존재하지 않을 경우 2 
sed,a자 등은 검색의 성공 여부에 대한 종료 상태값을 반환하지 않는다. 다만 구문 에러가 있을 경우에만 에러를 보고한다.

3.2 정규표현식을 사용하는 grep의 예제 
# grep NW datafile 
# grep NW d* 
(d로 시작하는 모든 파일에서 NW를 포함하는 모든 행을 찾는다.) 
# grep '^n' datafile 
(n으로 시작하는 모든 행을 출력한다.) 
# grep '4$' datafile 
(4로 끝나는 모든 행을 출력한다.) 
# grep TB Savage datafile 
(TB만 인자이고 Savage와 datafile은 파일 이름이다.) 
# grep 'TB Savage' datafile 
(TB Savage를 포함하는 모든 행을 출력한다.) 
# grep '5.' datafile 
(숫자 5, 마침표, 임의의 한 문자가 순서대로 나타나는 문자열이 포함된 행을 출력한다.) 
# grep '.5' datafile 
(.5가 나오는 모든 행을 출력한다.) 
# grep '^[we]' datafile 
(w나 e로 시작하는 모든 행을 출력한다.) 
# grep '[^0-9]' datafile 
(숫자가 아닌 문자를 하나라도 포함하는 모든 행을 출력한다.) 
# grep '[A-Z][A-Z] [A-Z]' datafile 
(대문자 2개와 공백 1개, 그리고 대문자 하나가 연이어 나오는 문자열이 포함된 행을 출력한다.) 
# grep 'ss* ' datafile 
(s가 한 번 나오고, 다시 s가 0번 또는 여러번 나온 후에 공백이 연이어 등장하는 문자열을 포함한 모든 행을 출력한다.) 
# grep '[a-z]{9}' datafile 
(소문자가 9번 이상 반복되는 문자열을 포함하는 모든 행을 출력한다.) 
# grep '(3).[0-9].*1 *1' datafile 
(숫자 3,마침표,임의의 한 숫자,임의 개수의 문자,숫자 3(태그),임의 개수의 탭 문자,숫자 3의 순서를 갖는 문자열이 포한된 모든 행을 출력한다.) 
# grep '<north' datafile 
(north로 시작하는 단어가 포함된 모든 행을 출력한다.) 
# grep '<north>' datafile 
(north라는 단어가 포함된 모든 행을 출력한다.) 
# grep '<[a-z].*n>' datafile 
(소문자 하나로 시작하고, 이어서 임의 개수의 여러 문자가 나오며, n으로 끝나는 단어가 포함된 모든 행을 출력한다. 여기서 .*는 공백을 포함한 임의의 문자들을 의미한다.)

3.3 grep에 옵션 사용 
# grep -n '^south' datafile 
(행번호를 함께 출력한다.) 
# grep -i 'pat' datafile 
(대소문자를 구별하지 않게 한다.) 
# grep -v 'Suan Chin' datafile 
(문자열 Suan Chin이 포함되지 않은 모든 행을 출력하게 한다. 이 옵션은 입력 파일에서 특정 내용의 입력을 삭제하는데 쓰인다. 
# grep -v 'Suan Chin' datafile > black 
# mv black datafile 
) 
# grep -l 'SE' * 
(패턴이 찾아진 파일의 행 번호 대신 단지 파일이름만 출력한다.) 
# grep -w 'north' datafile 
(패턴이 다른 단어의 일부가 아닌 하나의 단어가 되는 경우만 찾는다. northwest나 northeast 등의 단어가 아니라, north라는 단어가 포함된 행만 출력한다.) 
# grep -i "$LOGNAME" datafile 
(환경변수인 LOGNAME의 값을 가진 모든 행을 출력한다. 변수가 큰따옴표로 둘러싸여 있는 경우, 쉘은 변수의 값으로 치환한다. 작은따옴표로 둘러싸여 있으면 변수 치환이 일어나지 않고 그냥 $LOGNAME 이라는 문자로 출력된다.)

3.4 egrep 
egrep(extended grep) : grep에서 제공하지 않는 확장된 정규표현식 메타문자를 지원  한다.
                                     grep와 동일한 명령행 옵션을 지원한다. 
egrep에서 지원하는 확장 메타문자
메타문자
기능
사용 예
사용 예 설명
+
선행문자와 같은 문자의 1개 혹은 임의 개수와 대응
'[a-z]+ove'
1개 이상의 소문자 뒤에 ove가 붙어있는 문자열과 대응. move,approve,love,behoove 등이 해당된다.
?
선행문자와 같은 문자의0개 혹은 1개와 대응
'lo?ve'
l 다음에 0개의 문자 혹은 하나의 문자가 o가 나오는 문자열과 대응. love,lve 등이 해당된다.
a|b
a 혹은 b와 대응
'love|hate'
love 혹은 hate와 대응.
()
정규표현식을 묶어준다
'love(able|ly)'
lovable 혹은 lovely와 대응.
'(ov)+'
ov가 한 번 이상 등장하는 문자열과 일치.

3.4.1 egrep 예제 
# egrep 'NW|EA' datafile 
(NW나 EA가 포함된 행을 출력한다.) 
# egrep '3+' datafile 
(숫자 3이 한 번 이상 등장하는 행을 출력한다.) 
# egrep '2.?[0-9]' datafile 
(숫자 2 다음에 마침표가 없거나 한 번 나오고, 다시 숫자가 오는 행을 출력한다.) 
# egrep ' (no)+' datafile 
(패턴 no가 한 번 이상 연속해서 나오는 행을 출력한다.) 
# egrep 'S(h|u)' datafile 
(문자 S 다음에 h나 u가 나오는 행을 출력한다.) 
# egrep 'Sh|u' datafile 
(패턴 Sh나 u를 포함한 행을 출력한다.)


3.5 고정 grep 과 빠른 grep 
fgrep : grep 명령어와 동일하게 동작한다. 다만 정규표현식 메타문자들을 특별하게 취급하지
          않는다. 
# fgrep '[A-Z]****[0-9]..$5.00' file 
([A-Z]****[0-9]..$5.00 이 포함된 행을 출력한다. 모든 문자들을 문자 자체로만 취급한다.) 


[출처] grep 계열 명령어 |작성자 박신양


반응형

'프로그래밍 > BASH SHELL' 카테고리의 다른 글

특정 파일 / 디렉토리 바꾸기 (쉘스크립트 포함)  (0) 2015.01.27
bash 프롬프트 howto  (0) 2015.01.27
정규표현식  (0) 2015.01.27
쉘 문법  (0) 2015.01.27
정규식 이해  (0) 2015.01.27

댓글()

정규표현식

프로그래밍/BASH SHELL|2015. 1. 27. 10:03
반응형

2.1 정규표현식

2.1.1 정의와 용례 
정규표현식 : 검색을 위해 사용되는 여러 문자들의 패턴. 
2.1.2 정규표현식 메타문자
vi,ex,grep,egrep,sed,awk 등의 모든 버전에서 사용 가능.
메타문자
기  능
사용 예
사용 예 설명
^
행의 시작 지시자
/^love/
love로 시작하는 모든 행과 대응
$
행의 끝 지시자
/love$/
love로 끝나는 모든 행과 대응
.
하나의 문자와 대응
/l..e/
l 다음에 두 글자가 나오고 e로 끝나는 문자열을 포함하는 행과 대응
*
선행 문자와 같은 문자의 0개 혹은 임의 개수와 대응
/*love/
임의 개수의 공백 문자 후에 love로 끝나는 문자열을 포함한 행과 대응
[]
[] 사이의 문자 집합 중 하나와 대응
/[Ll]ove/
love나 Love를 포함하는 행과 대응
[x-y]
[] 사이의 문자범위내에의 한 문자와 대응
[A-Z]ove/
A부터 Z까지 한 문자가 ove로 끝나는 경우와 대응
[^ ]
문자집합에 속하지 않는 한 문자와 대응
/[^A-Z]/
A와 Z 사이의 범위에 포함되지 않는 한 문자와 대응
메타문자로 사용하고 싶지 않은 경우
/love./
love가 마침표(.)로 끝나는 경우와 대응.
일반적으로 .는 임의의 한 문자를 의미
<
단어의 시작 지시자
/<love/
love로 시작하는 단어를 포함하는 행과 대응(vi,grep에서 지원)
>
단어의 끝 지시자
/love>/
love로 끝나는 단어를 포함하는 행과 대응(vi,grep에서 지원)
(..)
다음 사용을 위해 태그를 붙인다.
/(lov)able1er/
9개 태그를 쓸 수 있다. 왼쪽부터 순서대로 태그번호가 매겨진다. 예를 들어, 패턴 lov는 태크 1에 저장되고, 뒤에는 1로써 태그 값을 사용할 수 있다. 왼쪽 예제에서 검색 패턴은 lovable에 lover가 붙어 있는 문자열이 된다.(sed,vi,grep에서 사용 가능.)
x{m}
문자 x를 m번 반복한다.
o{5,10}
문자 o가 5회에서 10회 사이의 횟수로 연속적으로 나타나는 문자열과 대응
x{m,}.
적어도 m번 반복한다.
 
 
x{m,n}.
n회 이하 m회 이상 반복한다.
 
 

정규표현식 사용 예
사용 예
설        명
/love/
정규표현식은 love이다. 패턴 love는 자체로 검색 대상이 될 수도 있고, 또는 lovely,gloves,clover 등과 같이 다른 단어의 일부가 될 수도 있다.
/^love/
여기서 ^는 행의 시작 지시자라 한다. vi는 love로 시작하는 행만 찾는다. 즉, love가 행의 첫 문자열이어야 한다. love 앞에 빈 칸이나 다른 문자가 오면 안 된다.
/love$/
$는 행의 끝 지시자라 한다. vi는 love로 끝나는 행만 찾는다. 즉, love가 행을 끝내는 단어의 제일 마지막 부분의 문자열이고, love가 끝나면 새로운 행이 시작되어야 한다.
/l.ve/
.는 개행문자를 제외한 어떤 문자와도 대응된다. vi는 l 다음에 임의의 한 문자가 나오고 ve가 뒤따르는 문자열을 찾는다. 예를 들어 love나 live를 찾는다.
/o*ve/
*는 0개를 포함한 임의 개수의 선행 문자와 대응된다. 즉, 어떤 문자 다음에 붙어 나와서 그 문자에 대해서만 제어를 담당한다. 따라서 o와 ve 사이에 o가 한 번도 오지 않을 수도 있고 여러번 올 수도 있다 . 예를 들어, love,loooove,lve 등을 찾아 준다.
/[Ll]ove/
[]는 괄호 안의 문자들 중의 하나와 일치하면 찾는다. vi는 ove 앞에 대문자 L이나 소문자 l이 오는 단어들을 찾아준다.
/ove[a-z]/
ove 다음에 아스키코드 상에서 a와 z 사이의 문자가 오는 문자열을 찾아준다. 문자 범위는 아스키 코드를 사용하기 때문에 [z-a]처럼 나타낼 수는 없다.
/ove[^a-zA-Z0-9]/
[]안의 ^는 부정을 의미하는 메타문자이다. ove 다음에 a와 z, A와 Z 및 0과 9 사이에 오지 않는 문자를 가진 문자열을 찾는다. 예를 들어, ove 다음에 쉼표,스페이스,마침표 등 지정된 범위 밖의 문자들이 나오는 문자열을 찾는다.
:1,$s/tom/David/g
첫 번째 행에서 파일의 끝까지 나와 있는 모든 tom을 찾아 David로 바꿔라.
:1,$s/<[Tt]om>/David/g
첫 번째 행에서 파일의 끝까지 나와 있는 모든 tom 이나 Tom을 찾아 David로 바꿔라.
s: 치환하라.      g: 치환이 전 범위에서 일어나게 하라.

2.2 정규표현식 메타문자의 조합

사용 예
사용 예
설    명
/^[A-Z]..$/
행의 처음에 대문자가 하나 나오고, 다음에 임의의 두 문자가 나오며, 연이어 개행문자가 오는 문자열을 찾는다.
/^[A-Z][a-z ]*3[0-5]/
행의 처음에 대문자가 하나 나오고, 소문자나 스페이스가 0번 또는 여러번 반복되며, 이어서 3이 나오고, 마지막으로 0과 5 사이의 숫자가 오는 문자열을 찾는다.
/[a-z]*./
임의의 소문자가 0번 또는 여러번 이어지다가 마침표로 끝나는 문자열을 찾는다.
/^ *[A-Z][a-z][a-z]$/
행의 처음에 공백문자(탭은 공백문자로 취급되지 않는다)가 0번 또는 여러번 나오고, 이어서 대문자 하나와 두 개의 소문자가 그리고 마지막으로 개행문자가 오는 문자열을 찾는다.
/^[A-Za-z]*[^,][A-Za-z]*$/
행의 처음에 대문자나 소문자 하나가 0번 또는 여러번 나오다가 쉼표가 아닌 문자가 오며, 이어서 다시 대문자나 소문자 하나가 0번 또는 여러번 나오다가 마지막으로 개행문자가 오는 문자열을 찾는다.



[출처] 정규표현식 |작성자 박신양

반응형

'프로그래밍 > BASH SHELL' 카테고리의 다른 글

bash 프롬프트 howto  (0) 2015.01.27
grep 계열 명령어  (0) 2015.01.27
쉘 문법  (0) 2015.01.27
정규식 이해  (0) 2015.01.27
쉘 명령 기초  (0) 2015.01.27

댓글()

쉘 문법

프로그래밍/BASH SHELL|2015. 1. 27. 10:02
반응형
1. 매개변수(파라메타)
쉘 변수에는 세가지 유형이 있으며 이는 매개 변수로 알려져 있다. 그종류는 키워드 매개 변수, 위치 매개변수, 특수 쉘 매개변수 등이다.
1) 키워드 매개 변수
키워드 매개변수명은 알파벳 문자나 _ (밑줄) 문자로 시작 되어야 한다. 그리고 그 다음에는 알파벳이나 밑줄문자의 임의의 숫자가 올 수 있다. 그 값들은 다음과 같이 기록함으로써 키워드 매개변수에 배정된다.
변수=값 변수=값 ...
2) 위치 매개 변수
쉘 프로그램이 실행될 때마다 프로그램명은 변수 $0에 배정되고, 명령 라인에 타이프된 인수들은 변수 $1, $2, $3 ...에 배정된다. 위치 매개변수들 set 명령으로 값을 배정 받을 수 있다. $9 이상의 매개변수는 ${nn}으로 표현할 수 있다.
Examples: 
$ cat hi 
print hello $1 
$ hi there world 
hello there 

3) 특수 매개 변수
$#     프로그램에 전달된 인수들의 수 또는 set문 실행에 의해 세트된 매개 변수들의 수 
$*     $1, $2, $3 ...과 같은 모든 위치 매개변수들을 집단적으로 참조 
$@     $* 과 같이 위치 매개변수들을 집단적으로 참조 
$0     실행중인 프로그램 이름 
$$     실행중인 프로그램의 프로세스 번호 
$!     실행을 위해 백그라운드로 보내진 마지막 프로그램의 프로세스 번호 
$?     백그라운드로 실행되지 않은 마지막 명령의 종료 값 
$-     현재 설정된 옵션값 


2. 매개변수 치환
가장 간단한 경우로서, 매개변수의 값은 달러표시($)를 가진 매개 변수를 선행함으로써 접근될 수 있다. 매개 변수의 치환은 파일명 치환전에, 그리고 명령 라인이 인수로 분리되기 전에 쉘에 의해 수행된다.
$parameter 또는 ${parameter}
매개변수의 값을 치환한다. 
$ print $PWD ${11} $$ 
/usr/dgk arg11 1234 
$ file=test_f 
$ cp $file ${file}x 
$ 
$ ls -x 
$ test_f test_fx
${parameter:-value}
parameter의 값이 null이 아닌 경우 그값을 치환하고, null인 경우에는 value값만을 치환. 
$ EDITOR=/bin/ed 
$ echo ${EDITOR:-/bin/vi} 
/bin/ed 
$ EDITOR= 
$ echo ${EDITOR:-/bin/vi} 
/bin/vi 
$ echo $EDITOR 
$
${parameter:=value}
parameter값이 null이 아닌경우 그값을 치환하고, null인 경우 value값을 치환하고 그것을 parameter에 대입. 
$ unset x 
$ typeset -u x 
$ print ${x=abc} 
ABC 
$ 
$ BOOKS= 
$ : ${BOOKS:=$HOME/books} 
$ echo $BOOKS 
/usr/kys/books 
$ : ${BOOKS:=tester} 
$ echo $BOOKS 
/usr/kys/books 
$
${parameter:?value}
parameter 값이 null이 아닐경우 그값을 치환. 그렇지 않으면 value을 표준 에러에 기록하고 빠져나옴. 
만약 value가 생략되어 있으면 parameter와 메서지를 출력프로그램에서 요구되는 변수들이 모두 설정되었는지 또는 무효가 아닌지의 여부를 알아보기위해 쉽게 사용하여 체크할수 있다.
$ print ${foo?} 
ksh: foo: parameter null or not set 
$ BOOKS= 
$ : ${BOOKS:?"No BOOKS file"} 
No BOOKS file
${parameter:+value}
parameter가 null이 아닐 경우 value를 치환.  null인 경우 아무것도 치환하지 않음. 
$ set a b c 
$ print ${3+foobar} 
foobar 
$ 
$ toption= 
$ echo options: ${toption:+ "T mode"} 
options: 
$
${#parameter}
매개변수의 길이를 치환 
$ HOME=/home/klog 
$ print ${#HOME} 
10
$
${#array[*]} , ${#array[@]}
배열의 요소들의 수를 치환 
$ unset x 
$ x[1]=5 x[3]=8 x[6]=abc x[12]= 
$ print ${#x[*]} 
4
${parameter#pattern}
매개변수의 값을 치환하며 이때 pattern과 부합되는 왼쪽 부분은 제거된다. 쉘 화일명 치환문자들(*,?,[..],@,!)을 사용할 수 있다. 
$ cd $HOME/src/cmd 
$ print ${PWD#$HOME/} 
src/cmd 
$
${parameter##pattern}
가장 큰 pattern과 부합되는 왼쪽 부분은 제거된다. 
$ x=/one/two/three 
$ print ${x##*/} 
three 
$
${parameter%pattern}
pattern과 부합되는 오른쪽 작은 부분이 제거된다. 
$ x=file.c 
$ print ${x%.c}.o 
file.o 
$
${parameter%%pattern}
pattern과 부합되는 오른쪽 큰 부분이 제거된다. 
$ x=foo/fun/bar 
$ print ${x%%/*} 
foo 
$ 

3. 파일 입출력
1) 파일 열고 닫기
exec 명령을 아무런 아규먼터 없이 사용하여 현재 환경에서 파일을 열고 닫을 수 있으며, I/O 방향재설정 방법을 사용하며 이때 파일디스크립터 값은 0-9까지 사용할 수 있다.
Examples: 
exec 3< foo  <- foo을 파일디스크립터3 으로 지정하여 읽기위해 
open 
$ exec 3<&- <- 파일디스크립터3 을 close 



4. 다큐먼트, 반환값
1) 다큐먼트
문자 #로 단어가 시작된다면 셀은 라인의 나머지를 주석으로 취급하고 ksh이 실행하지 않는다
Examples: 
$ cat samp_1 
# This is comment line 
# pwd 
ls -x        # display listing of the directory 
$ samp_1 
samp_1 samp_2 samp_3 samp_4 samp_5 
$
2) 반환값
각각의 명령어는 반환값을 가진다. 명령어의 반환값은 조건 명령이나 순환명령에서 많이 사용된다. 반환값은 0에서부터 255의 값을 가진다.
반환값 0 은 정상적인 종료인 경우의 값이며 조건이나 순환명령어에서 TRUE로 사용되는 값이다. 그 이외의 모든 다른 값은 FALSE로 취급된다.
반환값 1은 명령의 실행이 실패한 경우 129-160은 명령어가 신호를 수신하고 종료한 경우에 발생되는 값이다.
ksh에서는 $? 변수에 가장 최근에 종료된 명령어의 반환값이 저장된다.
 
5. 병렬 프로세스 기능
병렬프로세스 기능은 동시에 실행되면서 상호간에 통신하고 동기화를 하는 프로세스간의 상호 작용 기능을 제공한다. 병렬프로세스의 시작은 명령어 라인의 끝에 "|&" 을 추가하므로서 구현할 수 있다.
기본적으로 병렬 프로세스의 표준입력은 그 프로세스의 부모 프로세스의 표준 출력과 연결되며, 병렬 프로세스의 표준 출력은 그 프로세스의 부모 프로세스의 표준 입력과 연결된다.
cat /etc/passwd |& 
while true 
do 
if [ -z "$FLINE" ] 
then 
  exit 0 
else 
  read -p FLINE 
fi 
echo $FLINE 
done 




6. 쉘 스크립트 실행 방법
1) . Script ( Dot Command )
도트 명령은 지시된 파일이 마치 그 파일로 부터의 라인들이 그지점에서 타이프 된 것처럼 쉘에 의해 판독되고 실행되도록 한다. file은 실행하도록 하는 것이 아니라 다만 읽기 쉽게 한다.
Examples: 
$ cat > .profile 
export PS1='$PWD> ' 
export PATH=$PATH:$HOME 
^d 
$ . .profile 
/home/edu01> _ 
-> 변경된 .profile의 내용을 로그아웃, 로그인 순서를 그치지 않고 현재 쉘에서 실행하여 사용자 환경을 지정할 수 있다.
2) ksh script_filename
서브쉘을 생성하여 그 쉘이 스크립트를 읽어서 실행하도록 한다. 이 경우 script_filename 파일이 실행 퍼미션이 지정되어 있지 않아도 된다.
Examples: 
$ cat > test_sub_shell 
echo "test execution of shell script file " 
echo $PWD 
^d 
$ 
$ ls -l test_sub_shell 
-rw-r--r-- 1 edu01 other 54 Jan 29 10:00 test_sub_shell 
$ ksh test_sub_shell 
test execution of shell script file 
/home/edu01 
$
3) chmod +x script_filename
script 파일에 실행 퍼미션을 설정하여 실행한다.
Examples: 
$ chmod +x test_sub_shell 
$ ls -l test_sub_shell 
-rwxr-xr-x 1 edu01 other 54 Jan 29 10:00 test_sub_shell 
$ test_sub_shell 
ksh: No such file or directory 
-> 현재 디렉토리 경로가 PATH에 설정되어 있지 않다. 
$ export PATH=$PATH:. 
-> 현재 디렉토리를 PATH 환경변수에 설정한다 
$ test_sub_shell 
test execution of shell script file 
/home/edu01 
$
7. 파일과 문자 테스트 연산자
test 명령이나 [ ... ] 연산 결과 TRUE로 반환 받는 조건이다.
1) 파일연산자
-r     file 프로세스에 의해 판독가능한 파일 
-w     file 프로세스에 의해 기록 가능한 파일 
-x     file 프로세스에 의해 실행 가능한 파일 
-f     file 보통 파일 
-d     file 디렉토리 
-c     file 문자 특수 파일 
-b     2file 블록 특수 파일 
-p     file 파이프 파일 
-u     file 파일이 SUID(집합사용자 확인) 비트세트를 가진 경우 
-g     file 파일이 SGID(집합그룹확인) 비트 세트를 가진 경우 
-k     file sticky bit이 설정된 파일 
-s     file 비제로 길이를 가진 파일 
-L     file 심볼릭 링크 파일 
-O     file 파일의 주인이 effective user id인 경우 
-G     file 파일의 그룹이 effective user id인 경우 
-S     file socket 형태의 특수 파일인 경우 
-t     file file descriptor가 어떤 단말기와 연관된 개방된 파일 디스크립터인 경우 


2) 스트링 연산자
string              스트링이 널이 아닌 경우 
-n string           스트링이 널이 아닌경우 
-z string           스트링이 널인 경우 
string1 = string2   string1 과 string2 가 같은 경우 
string1 != string2 string1 과 string2 가 같지 않은 경우
3) 정수 비교 연산자
int1 -eq int2       int1 이 int2 와 같은 경우 
int1 -ge int2       int1 이 int2 와 같거나 그보다 큰경우 
int1 -gt int2       int1 이 int2 보다 큰경우 
int1 -le int2       int1 이 int2 와 같거나 작은 경우 
int1 -lt int2       int1 이 int2 보다 작은 경우 
int1 -ne int2       int1 이 int2 와 같지 않은 경우
4) 부울 연산자
!expr               expr이 FALSE 
expr1 -a expr2      expr1이 TRUE, 그리고 expr2가 TRUE 
expr1 -o expr2      expr1이 TRUE 혹은 expr2가 TRUE 


Examples: 
$ test -x file -a ! -d file 
-> file이 실행 가능하고 디렉토리가 아닌 경우 
$ test "x$1" = xabc 
-> $1이 abc인 경우 
$ [ "x$1" = xabc ] 
-> $1이 abc인 경우 
$ test ! ( -w file -o -x file ) 
-> file 이 쓸 수 있거나 실행 가능한 파일이 아닌경우 
$ [ ! ( -w file || -x file ) ] 
-> file 이 쓸 수 있거나 실행가능한 파일이 아닌경우 



8. 내장된 정수 연산
1) 정수 연산
일반적인 대부분의 수식 연산을 ksh 에서는 지원하고 있다. 다음은 ksh에서 지원 되는 연산자들이다.
-             단항 - 
~            NOT 
!            논리부정 
* , / , %    곱하기, 나누기, 나머지 
+ , -        더하기, 빼기 
<< , >>      왼쪽 시프트, 오른쪽 시프트 
< , > , <= , >=     비교 
== , !=      동등, 비동등 
&             그리고 
^             배타적 또는 
|             또는 
&&            논리적 and 
||            논리적 or 
=             배정 



2) let 명령
Korn쉘은 expr 명령없이 정수 연산을 수행하기 위한 메커니즘을 제공하고 있는데 그것이 let 명령이다. let은 쉘에 내장되어 있기 때문에 계산을 위한 새로운 과정을 만들거나 찾거나 프로그램을 로딩할 필요도 없다. let의 형식은
$ i=100 
$ let i = i + 1 
$ echo $i 
101 
$ 
$ let ' i = i + 1 ' 'j = j + 10'
개별적인 식들이 중간에 공백으로 가지고 있다면 인용부호로 묶어서 사용해야하며 이것은 수식 쉘로부터의 *, &, <, > 와 같은 문자들이 가지는 특별한 의미를 제거하는 부가적 효과를 가진다.
$ let 'i = ( i + 10 ) * j '
둥근 괄호를 이용하여 수식을 그룹화할 수도 있다.
 
3) (( expression ))
(( expression )) 은 let "expression" 과 같은 의미이다. 쌍으로된 둥근 괄호를 이용하여 let에 대한 대안적 형식을 취할수 있다.
$ (( i = i * 5 )) 
$ (( i >= 0 && i <= 100 ))
4) expr
expr 명령을 사용하여 수식 계산을 실행한 후에 변수에 그 값을 지정한다.
Examples: 
$ aa=10 
$ aa=`expr $aa + 10` 
$ echo $aa 
20 
$
5) integer variable
수식계산에 사용되는 변수를 정수로 선언하여 일반적인 형태의 수식계산 방식을 ksh에서 사용하도록 지정한다. 하지만 이렇데 지정된 변수는 반드시 정수 값만 가질수 있다.
Examples: 
$ integer aa 
$ aa=100 
$ aa=aa+1 
$ echo $aa 
101 
$ aa="test a integer variable" 
ksh: aa: bad number 
$

9. 배열
Korn쉘은 제한된 배열 능력을 제공한다. 배열은 1차원으로 512요소를 가지며, 배열의 인덱싱은 0에서 시작하고 511까지 지정할수 있다.
배열의 요소는 한쌍의 각괄호( [ ] ) 안에 넣어진 정수값으로 된 색인첨자와 함께 호출되는 것으로 자신이 요구하는 만큼 요소에 값을 할당하여 사용한다.
$ arr[0]=hello 
$ arr[1]="some text" 
$ arr[2]=/home/dgk/memos
배열로부터 값을 불러오는 방법은 배열의 이름과 각 괄호안에 원하는 요소의 번호를 넣고 그것을 ${ }에 넣어 사용한다.
$ echo ${arr[0]} 
hello 
$ echo ${arr[2]} 
/home/dgk/memos 
$ echo $arr 
hello 
-> 첨자가 없는 경우 요소 0이 이용된다. 
$ echo $arr[1] 
hello[1] 
-> { }을 사용하지 않고 출력한 경우 예상치 않은 결과 값을 출력한다. 
$ 
$ echo ${arr[*]} 
hello some text /home/dgk/memos 
-> 배열에 들어있는 모든 내용을 불러 온다 
$ 
$ echo ${#arr[*]} 
3 
-> 배열 arr에 있는 요소들의 갯수. 이때 수는 실제 요소의 갯수가 아니고 가장 큰 첨자 + 1 한 값이 출력된다. 이 값은 배열안에 다음 요소를 저장하기 위한 첨자로 사용된다. 
$ 
$ arr[10]=foo 
$ echo ${arr[*]} 
hello some text /home/dgk/memos foo 
$ echo ${#arr[*]} 
11 
-> 사용자가 정수 명령을 배열명에 선언해 줌으로써 Korn쉘에게 정수 배열을 선언하게 한다. 
$ integer arr 
$ arr[0]=100 
$ arr[1]=50 
$ (( arr[2] = arr[0] + arr[1] )) 
$ echo ${arr[2]} 
150 
$ 


배열구성요약
${array[i]} 요소 i 값을 치환 
$array 첫번째 요소 array[0]값을 치환 
${array[*]} 모든 요소값을 치환 
${#array[*]} 요소들의 수를 치환 
array[i]=value value을 array[i]로 치환
 
10. 함수 정의
ksh에서의 function명령은 name ( ) { ....; } 형식으로 선언된다. 기능을 분류하거나 순환적으로 일어나는 일들을 하나의 변수 형식으로 지정하여 불러 사용할 수 있도록 한다.
function identifier 
{ 
       compound-list 
} 
identifier( ) 
{ 
       compound-list 
}
Examples: 등록된 사용자수를 세는 nu 라는 함수를 정의한다. 
$ function nu 
> { 
> who | wc -l 
> } 
$ nu 
13 
$ 

$ cat funt1 
function check_yesno 
{ 
 typeset -l reply 
 while true 
 do 
 read -r "reply?$1? " || return 1 
 case $reply in 
       y|yes} return 0;; 
       n|no) return 1;; 
       *) print 'please answer y or n';; 
 esac 
 done 
} 
while check_yesno 'Do you want to continue? ' 
do 
 foobar 
done 
$
일반적으로 정의된 함수는 서브쉘에 보내지지 않는다. 하지만 typeset이라는 명령을 사용하여 함수정의를 export 시킬 수 있다.
$ typeset -fx funtion-name 
-> function-name을 주지 않으면 엑스포트된 함수들의 명단을 출력한다. 

$ typeset -f -> 정의된 함수의 리스트를 출력한다. 
funcrion nu 
{ 
who | wc -l 
} 
$
함수정의 삭제
함수정의를 삭제하기 위해 -f 옵션을 가진 unset명령을 사용한다.
$ type nu 
nu is a function 
$ unset -f nu 
$ type nu 
ksh: nu: not found 
$ 


11. 변수의 속성 정의
매개변수의 종류는 앞에서 키워드 매개변수, 위치매개변수, 특수매개변수로 나누어 설명하였다. 이런 각각의 변수는 하나 또는 그 이상의 특성을 정의할 수 있으며 typeset 이라는 명령어를 사용하여 변수의 특성을 on/off 하거나 설정되어 있는 내용을 리스트할 수 있다.
Command: typeset [-options] vasriable 
Options:
-u Uppercase      소문자를 대문자로 변환한다. -l 옵션은 자동적으로 off된다
$ typeset -u x=abc 
$ print $x 
ABC
-l Lowercase      대문자를 소문자로 변환한다. -u 옵션은 자동적으로 off 된다.
$ typeset -l x=ABC 
$ print $x 
abc
-i or -ibase Integer    정수 변수로 정의된다. base는 수의 진법 정의
$ integer x=6 
$ typeset -i8 y=x+x 
$ print $y 
8#14
-L or -Lwidth Left-justified        앞에오는 공란들을 왼편 자리 맞춤시키고 스트립 시킴. width가 비제로로 정의 되어 있으면 자리수를 width로 설정한다. -R옵션은 자동적으로 off된다.
$ typeset -L3 x=abcd y 
$ y=3 
print "$y-$x" 
3 -abc
-LZ or -LZwidth Strip Leading Zero       앞에오는 제로들은 스트립되고 왼편으로 자리 맞춤한다.
$ typeset -LZ3 x=abcd y 
$ y=03 
print "$y-$x" 
3 -abc
-R or -Rwidth Right-justified       오른편 자리 맞춤시키고 스트립시킴. width가 비제로인 경우 자리수를 width 로 설정.
$ typeset -R3 x=abcd y 
$ y=3 
$ print "$y-$x" 
3-bcd 

-Z or -Zwidth Zero-filled 
-RZ or -RZwidth Zero-filled
-Z만 설정된 경우 -L 옵션이 굛 되어있지 않다면 오른편로 자리 맞춤 시키고 스트립시킨다. width가 비제로 값이면 자리수를 width로 설정한다. 만약 처음의 비공란 문자가 숫자이면 0으로 채워진다.
$ typeset -Z3 x=abcd y 
$ y=3 
$ print "$y-$x" 
003-bcd
-r Read-only      변수가 읽기전용으로 설정되어 있다면 그 변수값을 변경하려 하면 에러 메세지를 출력하고 변경이 불가능하다.
$ typeset -r foo=bar 
$ foo=nobar 
ksh: foo: is read only 
$ unset foo 
ksh: foo: is read only
-x Exported        모든 변수에 값이 설정되면 자동적으로 현재 환경에 값을 배당한다.
$ typeset -x foo=bar 
$ export foo=bar 

12. 패턴
[ . . . ] 부호     문자들을 정의하여 그중 어느 하나의 문자와 일치하는 패턴 정의할수 있다. ' - ' 부호를 사용하여 범위를지정 할수 있다. ' ! ' 부호를 사용하여 역으로 매치 시킬수도 있다.
$ ls 
chap1 chap10 chap11 chap2 chap3 chapa chapb chapc 
$ ls chap[123] 
chap1 chap2 chap3 
$ ls chap[12][01] 
chap10 chap11 
$ ls chap[!2-4] 
chap1 
$ ls chap[1-3] 
chap1 chap2 chap3
? 문자       어떤 문자이든 상관없이 한 문자와 매치 된다
$ ls chap? 
chap1 chap2 chap3 
chapa chapb chapc
* 문자       어떤 문자든 0번 또는 그 이상과 매치
$ ls chap* 
-> chap 으로 시작되는 모든 스트링 
$ ls x*y 
-> x로 시작하고 y로 끝나는 모든 스트링
?(pattern[|pattern]...) 패턴         0번 또는 한번 발생되는 pattern과 매치
$ ls para?([345]|99)1 
-> para1, para31, para41, para51, para991 과 매치
*(pattern[|pattern]...) 패턴         0번 이상 발생되는 pattern과 매치
$ ls para*([0-9]) 
-> para, para뒤에 어떤 숫자라도 붙어 있는 스트링과 매치
+(pattern[|pattern]...) 패턴         1번 이상 발생되는 pattern과 매치
$ ls para+([0-9]) 
-> para뒤에 숫자가 붙어 있는 모든 스트링과 매치
@(pattern[|pattern]...) 패턴        정확히 한번 발생되는 pattern과 매치
$ ls para@(chute|graph) 
-> parachute, paragraph 과 매치
!(pattern[|pattern]...) 패턴         pattern에 정의된것을 제외한 모든것과 매치
$ ls para!(*.[0-9]) 
-> para로 시작하고 .숫자로 끝나지 않는 모든 스트링과 매치 


13. 조건문
[ [ test-expression ] ] 또는 [ test-expression ] 기호
test 명령을 대신하여 테스트하는데 사용할 수 있다. 
$ [ [ foo > bar && $PWD -ef . ] ] && print foobar 
foobar
1) if . . . then . . . else . . . fi
if 는 일반적으로 3가지 패턴으로 사용할수있다.
형식1:
if test -f $1 
then 
  echo $1 exist 
fi
형식2:
if test -f $1 
then 
echo $1 exist 
else 
  echo $1 does not exist 
fi 

형식3:
if (( score < 65 ) 
then grade=F 
elif (( score < 80 ) 
then grade=C 
elif (( score < 90 ) 
then grade=B 
else grade=A 
fi
Examples:
if print 'Please enter your name: c' ; read -r name 
then if mail "$name" < mailfile 
     then : 
     else print "Cannot mail to $name" 
     fi 
else print 'end-of file'
     exit 1 
fi
2) case
case word in 
[ ( ) pattern [ | pattern.... ] ... ] compound-list ;; ] 
. . . . 
esac
word와 매치되는 pattern을 찾아서 해당되는 compound-list를 실행한다.
Examples:
$ cat case1 
case $x in 
-d*) dflag=1;; 
-e*) eflag=1;; 
"") print -r -u2 - "x must have a value";; 
*) if test ! -r "$x" 
   then print -r - "$x: no read permission" 
   fi ;; 
esac
$ cat case2 
read -r line 
case $line in 
[$1]*) : ;; # ok 
*) print 'Line must begin with one of: $1" 
   exit 1;; 
esac 



14. 반복
1) for 문
for identifier [ in word .... ] 
do compound-list 
done
word의 개수만큼 do와 done사이의 명령어들을 반복적으로 실행한다
Examples: 
$ cat for1 
for i in apple banana mango 
do 
  echo "$it" 
done 
$ 
$ for1 
apple banana mango 
$ 
$ cat for2 
for i in *   ## 현재 디렉토리의 모든 파일 
do 
if test -d "$i" 
then print -r - "$i" 
fi 
done
다음 예제는 트럼프 놀이를 쉘 스크립트로 작성한 것이다. 한번 <Enter> 키를 칠 때 마다 카드 번호를 한 장씩 출력해준다. 총 7장의 카드를 출력해준다.
$ cat for3 
integer i=0 ; typeset -u card 
echo "Gamer I : 이름을 입력하시오: c" 
read gamer01 
echo "Gamer II : 이름을 입력하시오: c" 
read gamer02 
echo "카드를 섞고 있습니다" 
for suit in clubs diamonds hearts spades 
do 
  for n in ace 2 3 4 5 6 7 8 9 10 jack queen king 
  do 
  card[i]="$n of $suit" 
  i=i+1 
  done 
done 
echo "게임을 시작하겠습니다" 
for gamer in $gamer01 $gamer02 
do 
  echo "$gamer: c" 
  i=0 
  while [ $i -le 7 ] 
  do 
    read 
    echo " ${card[RANDOM%52]} t" 
    i=i+1 
  done 
  echo 
done 

2) select문
select identifier [ in word .... ] 
do compound-list 
done
나열하는 word를 화면에 메뉴 형태로 표준 출력 화면으로 출력해 주고, 표준 입력으로부터 무한 반복으로 값을 입력 받는다. 값을 입력 받기위해 프롬프트를 출력해 주는데 디폴트 프롬프트는 '?' 이다. 프롬프트는 환경변수 PS3에서 지정할 수 있다.
Examples:
$ cat select1 
PS3='Please enter a number: ' 
select i in add delete modify list exit 
do 
  case $i in 
  add|modify) 
    print Select editing file 
    break;; 
  delete) 
    print Select removing job;; 
  list) 
    print Select display job;; 
  exit) 
    print Select exit job 
    print Good-bye 
    exit ;; 
  *) print 'Invalid number';; 
  esac 
done
$ select1 
1) add 
2) delete 
3) modify 
4) list 
5) exit 
Please enter a number:_ 



3) while문
while test문 또는 명령어 실행 
do compound-list 
done
while 반복문은 test문 또는 명령의 실행결과가 참(true)인 동안 루틴을 반복적으로 수행한다.
Examples:
$ cat while1 
while read -r line 
do 
  print -r - "$line" 
done 

$ cat while2 
while [ $line -le $maxline ] 
do 
  echo >> $BUFFER 
  lines=`expr $lines + 1` 
done
$ cat while3 
while true 
do 
  read name 
  if [ ${name}x = x ] 
  then 
    break 
  fi 
done
4) until 문
until test문 또는 명령어 실행 
do compound-list 
done
test문 또는 명령 실행결과가 거짓(false)인 경우 루틴을 반복 수행한다.
Examples:
$ cat until1 
until cc -c foo.c 
do vi foo.c 
done
$ cat until2 
until who | grep klog >/dev/null 
do 
echo waiting 5 seconds 
sleep 5 
done 
echo klog has logged on
$ cat until3 
until false 
do 
  read name 
  if [ ${name}x = x ] 
  then 
    break 
  fi 
done 

15. 흐름 제어
1) break [ n ]
이 명령의 실행은 가장 안쪽 n개의 for, while, until 루프의 실행이 즉시 종료시키고 빠져 나오며 루프다음의 명령을 계속 실행한다.
Examples:

$ cat break1 
for i in * 
do
  for j in foo bar bam 
  do 
     if test "$j" = "$i" 
     then 
        break 2 
     fi 
  done 
done


2) continue [ n ]
for, while, until 루프안에서의 이명령의 실행은 continue 다음에 오는 임의의 명령들이 skip 되도록 한다.
Examples:
$ cat continue1 
for i in * 
do 
  if test -d "$i" 
  then continue 
  fi 
  print -r - "$i is not a directory" 
done 
$ 


16. 쉘 프로그래밍 응용
1) vi with backup the file
vi 편집기를 호출하여 파일을 편집하여 저장하기전 이전의 파일을 filename.bak 파일에 저장하도록 하는 쉘 스크립트를 작성한다.
$ cat vvi 
#!/usr/bin/ksh 
# 
if [ $# -le 0 ] 
then 
vi 
exit 
fi 
cp $1 ${1}.tmp 
vi $1 
if cmp -s $1 ${1}.tmp 
then 
  rm ${1}.tmp 
else 
  cp ${1}.tmp ${1}.bak 
  rm ${1}.tmp 
fi
 
2) newcat
출력용 필터인 newcat 을 생성한다. 내용의 각 라인에 라인번호를 붙여서 23개 라인씩 출력한다.
$ cat newcat 
#!/usr/bin/ksh 
if [ $# -lt 1 ] 
then 
  echo "Usage Error: newcat filenames... " ; exit 
fi 
for filename in $* 
do 
  integer count=1 
  integer page=1 
  exec < $filename 
  echo "Filename : $filenamettPage: $page " 
  while read line 
  do 
    if [ $count -eq 22 ] 
    then 
       echo "--More-- <Press Return> " 
       read 
       echo "f" 
       page=page+1 
       echo "Filename : $filenamettPage: $page " 
    fi 
    echo "$countt$line" 
    count=count+1 
   done 
done
3) exec_check 실행 점검 스크립트
program_01 이라는 프로그램을 실행하는 스크립트를 작성한다. 이미 이 프로그램이 실행중이라면 30초간 대기하면서 이미 실행중인 프로그램의 실행종료를 대기한다. 대기중 실행종료가 확인되면 프로그램을 실행시킨다. 30초가 초과되면 타임아웃으로 인식하고 메시지를 출력하고 스크립트를 종료한다.
$ cat exec_check 
#!/usr/bin/ksh 
# 
trap "echo off > ex_check_file; echo "인터럽트 수신/종료"; exit 200" 2 
if [ $# -ne 1 ] 
then 
  echo "실행할 프로그램명이 입력되지 않았습니다" 
  echo "USAGE: exec_check program-name" 
  exit 
fi 
if [ ! -f ex_check_file ] 
then 
  echo off > ex_check_file 
fi 
integer count=0 
while read e_flag < ex_check_file; [ e_flag = 'on' ] 
do 
  echo "$1 프로그램이 실행중입니다. 프로그램 종료 대기중..." 
  sleep 5 
  count=count+1 
  if [ $count -eq 6 ] 
  then 
    echo "TIME OUT...." 
    echo "$1 프로그램이 아직 실행중입니다" 
    echo "잠시후 다시 실행하여 주십시오" 
    echo "스크립트를 종료합니다" 
    exit 
  fi 
done 
echo on > ex_check_file 
$1 
echo off > ex_check_file 
echo "$1 프로그램 실행을 정상 종료합니다" 


4) 웹으로 finger을 실행하게 하는 CGI 프로그램
#!/bin/sh !/usr/bin/ksh 
FINGER=/usr/bin/finger
 
echo Content-type: text/html
 
echo
 
if [ -x $FINGER ]
 
then
 
  
if [ $# -eq 0 ]
 
  
then
 
    
cat << EOM
 
    
<HTML>
    <HEAD><TITLE>Finger Gateway</TITLE></HEAD>
 
    
<BODY>
 
    
<H1>Finger Gateway</H1>
 
    
<ISINDEX>
 
    
This is a gateway to "finger". Type a user@host combination in your browser's search dialog.<P>
 
    
EOM
 
  
else
 
    
echo <PRE>
 
    
$FINGER "$*"
 
    
echo </PRE>
 
  
fi
 
else
 
  
echo Cannot find finger on this system.
 
fi
 
cat << EOM
 
</BODY></HTML>
 
EOM 


[출처] 쉘 문법 |작성자 박신양


반응형

'프로그래밍 > BASH SHELL' 카테고리의 다른 글

grep 계열 명령어  (0) 2015.01.27
정규표현식  (0) 2015.01.27
정규식 이해  (0) 2015.01.27
쉘 명령 기초  (0) 2015.01.27
쉘 프로그래밍 (shell programming)  (0) 2015.01.27

댓글()

정규식 이해

프로그래밍/BASH SHELL|2015. 1. 27. 10:02
반응형
1. 정규식에 대한 이해
grep,awk,sed,vi,perl등과 같은 명령어들을 패터처리 언어에서 사용하는 패턴에 대한 특정 규칙을 정규식(Regular Expression)이라고 부른다. 다시 말해서 패턴이란 "규칙적으로 기술된 문자열" 이라고 설명 할 수 있고 이런 규칙들을 표현하는 형식중의 한 방법이 정규식이다.
다음은 샘플 데이터 파일과 egrep 명령을 이용하여 정규식을 하나씩 설명하겠다.
<샘플 파일> 
$ cat sampfile 
This is sample data file 
Hello This is Kim. 
I'm so happy 
Test100 
test200 
Are you unhappy ?
1) " ^ " : 행의 시작과 부합
$ grep "^H" sampfile 
Hello This is Kim.
2) " $ " : 행의 끝과 부합
$ grep "happy$" sampfile 
I'm so happy
3) " * " : 임의의 0개 이상의 문자와 부합
$ egrep "e*" sampfile 
This is sample data file 
Hello This is Kim. 
I'm so happy 
Test100 
test200 
Are you unhappy ? 
$ egrep "ee*" samplefile 
This is sample data file 
Hello This is Kim. 
Test100 
test200 
Are you unhappy ? 
$ egrep "ppp*" sampfile 
I'm so happy 
Are you unhappy ?
4) " ? " : 임의의 0 또는 1개의 문자와 부합
$ egrep "pp?" sampfile 
This is sample data file 
I'm so happy 
Are you unhappy ? 

5) " + " : 임의의 1개 이상 문자와 부합
$ egrep "pp+" sampfile 
I'm so happy 
Are you unhappy ?
6) " . " : 임의의 한문자와 부합
$ egrep "y.." sampfile 
Are you unhappy ?
7) " < " : 단어의 시작과 부합
" > " : 단어의 끝과 부합 
$ egrep "happy" samplfile 
I'm so happy 
Are you unhappy ? 
$ egrep "<happy>" sampfile 
I'm so happy 
$ egrep "happy>" sampfile 
I'm so happy 
Are you unhappy ? 

8) " [문자들] " : 문자들에 포함되는 하나의 문자와 부합
" ^[문자들] " : 문자들에 포함되는 문자들을 제외한 하나의 문자와 부합 
$ egrep "^[A-Z]" sampfile 
test200 
$ egrep "^[^A-Z]" sampfile 
This is sample data file 
Hello This is Kim. 
I'm so happy 
Test100 
Are you unhappy ? 
$ egrep "[0-9]$" sampfile 
Test100 
test200
9) 정규식과 부합하는 문자의 반복횟수
{숫자} : 정확히 지정된 숫자만큼 반복 
{최소값,최대값}: 최소값부터 최대값까지 횟수 만큼 반복 
ex) a{1} a가 정확히 한번 team , happy, goal 
a{1,} a가 한번이상 반복 team. aang, aaaang 
a{2,5} a가 2번이상 5번 이하 반복 aa, aaa, aaaa, aaaaa 

10) " ( 패턴 ) " : 내부 표현식을 만든다.
패턴을 하나의 문자 처럼 사용한다. 
" 숫자 " : 숫자번째 내부 표현식에 부합된 문자열을 다시 참조한다.
 
$ egrep '([A-Za-z0-9].*)(:.*){4}:/export/home/1:' /etc/passwd 
결과> /etc/passwd 파일안에서 사용자의 login명과 기본 디렉토리명이 같은 사용자를 검색하여 출력한다.
11) " " : 정규식의 메타 문자가 아닌 문자 자체로 해석
$ egrep ".$" sampfile 
Hello This is Kim. 

2. awk
awk 은 설계자인 Aho, Weingrger, Kernighan의 첫글자로 명명되어진 패턴검색과 처리 기능을 가진 인터프리티드 프로그래밍 언어로서 필터링, 치환, 간단한 리포팅 작업을 제어할수 있다.
1) "awk" 형식
awk 프로그램은 세부분으로 구성되어 진다.
BEGIN Section : 파일을 읽기전에 실행 
Pattern Statment Section : 파일의 각 레코드 라인을 읽어들일 때 마다 실행 
END Section : 파일을 다 읽어들인 뒤 실행
BEGIN { statements ….} 
/pattern expression / { statements  .... } 
END { statements… }
 
여러개의 statement를 한 라인에 쓸때는 statement ; statement 의 형식으로 기술한다. 

2) awk 명령어 실행 방법
"awk" 프로그램을 명령어 상에서 입력하는 경우 
$ awk '{print $0 }' datafile .... 
단일인용문( ' ' ) 안에 프로그램을 기술한다. 데이터 파일을 정의하지 않으면 표준 입력으로부터 데이터를 입력 받는다.
awk 프로그램을 파일로 작성하는 경우는 
$ awk -f awk-program-filename data-filenames
ex) 
$ awk ' BEGIN { print "awk 프로그램 실행 연습입니다" } ' 
$ 
$ awk '{ print $1, $2 } ' data1 
100 200 
300 400 
500 600 
$ 
$ cat ex01 
# This is sample file 
BEGIN { 
print "Hello, I'm Kim " 
exit } 
$ 
$ awk -f ex01 
Hello, I'm Kim
$ 

3) 레코드
레코드는 입력된 파일의 한 줄을 말한다. 라인 전체의 내용은 $0 변수명으로 사용되며, 입력된 레코드 번호는 NR 이라는 변수로 표시 된다.
4) 필드
입력된 레코드에서 스페이스 또는 탭으로 구분되는 문자들을 말한다. 각각의 필드는 $1,$2,$3,....$n 으로 필드위치에 따라 변수명으로 표기되며 현재 필드값은 NF 변수로 표시된다.
5) 변수
위치변수 는 필드 또는 레코드를 나타낸다. 
$0 : 현재 입력된 레코드를 나타내는 변수 
$1 : 현재 입력된 레코드의 첫 번째 필드를 나타내는 변수 
$n : 현재 입력된 레코드의 n번째 필드를 나타내는 변수
재정의 변수는 입력된 레코드의 구성과 크기에 대한 정보를 제공한다. 
NR : 레코드 수 
NF : 필드 수 
FS : 필드 구분 문자 
RR : 레코드 구분 문자 
OFS : 출력 필드 구분 문자 
ORS : 출력 레코드 구분 문자 
FILENAME : 현재 입력된 파일 이름 
OFMT : 출력 인쇄 형식
사용자 정의 변수는 프로그램의 어느 곳에서도 사용자가 정의하여 사용 할 수 있으며, 숫자 또는 문자열 값을 가진다. 초기화 하지 않으면 자동적으로 null(0) 문자를 가진다.
ex) 
$ cat data1 
100 200 
300 400 
500 600 
$ cat ex02 
BEGIN { OFS="------" } 
{ print $1,$2 } 
$ 
$ awk -f ex02 data1 
100------200 
300------400 
500------600 
$ 
$ cat ex03 
{ x = $1 + $2 
y = y + x } 
END { print y } 
$ 
$ awk -f ex03 data1 
1600 
$ 

6) 패턴 과 연산자
패턴의 형식은 egrep과 유사한 형식을 가진다. 정규식을 사용하여 패턴을 구성할 수 있으며 패턴은 "/ /" 형식으로 지정한다. 
"/ /,/ /" 형식을 사용하여 패턴으로 범위를 지정할 수 있다.
ex)
$ cat ex04 
$2 ~ /^[0-9]+$/ { print $2 } 
-> 두 번째 필드가 숫자로만 구성되어 있으면 두 번째 필드값을 출력 
$ awk -f ex04 data1 
200 
400 
600 
$ 
$ cat ex05 
$0 ~ /[Ee]nd/ { print "end of", FILENAME } 
$ 
-> 읽어 들인 레코드의 값이 End 또는 end이면 "end of data1" 과 같은 형식으로 출력 
$ cat ex05_1 
/Begin/,/End/ { total += $1 } 
END { print "Total = " total }
연산자는 관계연산자, 패턴 연산자, 산술연산자, 지정 연산자, 복합지정연산자, 증감연산자 가 있다. 
관계연산자는 숫자 또는 스트링 값을 비교할 때 사용한다.
==            같다 
!=           같지 않다 
>             크다
<             작다 
>=            크거나 같다 
<=            작거나 같다
ex)
NF != 5 { print "필드수가 5개가 아님"} 
$1 >= 10000 { print "첫번째 필드값이 10000 보다 크거나 같다" } 
$1 >= "s" { print " 첫 번째 필드가 s 보다 뒷문자(tuvw..)이다"} 
$1 < $2 { print "두번째 필드 값이 첫 번째 필드 값보다 크다"}
패턴연산자는 스트링 패턴과의 일치 여부를 비교할 때 주로 사용 된다.
~             패턴과 일치 
!~           패턴과 같지 않다.
ex) 
$1 !~ /^[0-9]+$/ { print "첫번째 필드가 숫자가 안니다" } 
$2 ~ /korea/ { print "두번째 필드값이 korea 이다"}
산술연산자는 수식 계산에 사용된다 
+             더하기 
-             빼기 
*             곱하기 
/             나누기 
%             나누어서 남은 나머지
지정 연산자는 오른쪽 값을 왼쪽 변수에 대입한다 
=             지정연산 
ex) a = 10
복합 지정 연산자는 산술연산자와 지정연산자를 결합해서 사용한다 
+= , -=, *=, /=, %=
ex) a += 5 : a = a + 5 와 같은 문장이다.
증감 연산자는 값을 1씩 증가하거나 감소 시킬 때 사용한다
++           1 증가 
--           1 감소
ex) 
$ cat ex06 
END { a = 0 
print "a++ = ", a++ 
print "a-- = ", a-- 
exit 
}
$ cat ex07 
BEGIN { a = 0 } 
$1 > 100 { a++ } 
END { print "첫번째 필드의 값이 100보다 큰 경우는 ", a, "번입니다" }
$
$ awk -f ex07 data1 
첫번째 필드의 값이 100보다 큰 경우는 2 번입니다
7) 출력문
print 문은 출력하고자하는 문자열은 "출력내용" 의 형식으로, 변수값은 변수명을 사용하여 출력한다. 
" , " (쉼표)는 "print"문 안에서 필드를 구분한다. "" 사이의 문자열은 하나의 필드로 취급된다. 
출력방향을 조정하기위해 " > " 문자와 " >> " 문자를 사용할수 있다. 출력될 파일이름은 인용부호("")안에서 사용한다.
ex) 
$ cat ex08 
{ print $1,$2 > "sample"} 
$ 
$ awk -f ex08 data1 
$ cat sample 
100 200 
300 400 
500 600
"printf" 문을 사용하여 출력 양식을 지정할 수 있다. 
사용형식은 printf "format",expression1, expression2,..... 이다. 
format에서 변환사양은 % 기호를 붙여서 표시한다
%d            십진수 
%o            8진수 
%x            16진수 
%s            문자열 
%f            소수 
%e            지수를 사용한 소수 
%g            %f,%e중 짧은 형태의 출력을 사용한다.
ex) 
$ cat ex09 
$1 ~ /^[0-9]+$/ { printf "첫번째 필드 값은 %d 입니다n",$1 } 
$ 
$ awk -f ex09 data1 
첫번째 필드 값은 100 입니다 
첫번째 필드 값은 300 입니다 
첫번째 필드 값은 500 입니다 
$
파이프(|)를 사용하여 " print"문의 출력을 UNIX 시스템 명령어의 입력으로 사용할 수 있다. awk 안에서 유닉스 명령과 인수를 사용하는 경우는 인용부호(" ")로 묶어서 사용한다.
$ cat ex09 
END { print " Pipe Test ...Is it OK? " | "mail guest" } 
$ 
$ awk -f ex08 data1 
$ login guest 
Welcome to guest account 
You have mail 

8) 프로그래밍 언어 구조 제어문들
" if " 문
ex)
{ if ( $1 < 100 && $2 > $3 ) 
{ print "첫번째 필드값이 100보다 작고 두 번째 필드값이 세 번째 필드값 보다 큽니다" } 
}
ex) 
{ if ( $1 > 100 || $2 >100 ) 
{ print "첫번째 필드값이 100보다 크거나 두 번째 필드값이 100보다 큽니다" } 
}
" while " 문
{ i = 1 
while ( i <= NF ) 
{ print "필드수가 1개보다 작거나 같습니다" } 
}
" for " 문
ex) 
$ cat ex10 
{ for ( a = 1 ; a <= NF ; a++ ) print NR,a ,$a } 
$ awk -f ex10 data1 
1 1 100 
1 2 200 
2 1 300 
2 2 400 
3 1 500 
3 2 600 
$
" break "문은 순환문의 수행을 중지 시키고 순환문 밖의 문장을 수행한다 
" continue "문은 순환문의 수행을 중지하고, 순환문의 처음 조건을 테스트한다. 
" next " 문은 다음 입력 레코드를 읽어 들이고 프로그램 수행은 패턴문의 처음을 수행한다. 
" exit " 문은 프로그램 실행을 종료한다
ex) 
$ cat ex11 
{ for ( n = 1; ; n++ ) 
{ if ( n <= NF ) { print NR, n, $n 
  continue } 
  break 
} } 
$ 
$ cat ex12 
NF > 2 { print NR, NF; next } 
$ 
$ cat ex13 
$1 > 100 { print NR, " $2= ", $2, "$2값 오류" 
exit 99 } 
$
 
9) awk에서 많이 사용되는 함수들
" length " 함수는 주어진 문자열의 문자 개수를 반환한다. length 함수에 인수가 없으면 현재 입력 레코드의 문자수를 반환한다.
$ cat ex14 
{ print NR, "입력된 문자열의 문자수는 " , length, "개입니다" } 
$
$ cat ex15 
{ print NR, "첫번째 필드의 문자수는 ", length($1), "개입니다" } 
$
" substr " 함수는 지정한 문자열에서 원하는 개수 만큼의 문자들을 추출하여 반환한다
$ cat ex16 
BEGIN { 
print substr("Happy Birthday",7,9) 
exit }
$ awk -f ex16 
Birthday
" index " 함수는 문자열에서 지정하는 문자열이 있는 위치를 나타낸다. 문자열에서 지정한 문자열이 포함되어 있지 않은 경우는 0 값을 반환한다.
$ cat ex17 
BEGIN { 
print index("Hello This is Kim","This") 
exit 
}
$ awk -f ex17 
7 
$
" sprintf " 함수는 printf함수와 사용방법이 유사하지만 출력의 방향이 지정연산자의 왼편에 있는 변수명이다.
$ cat ex18 
{ var = sprintf("출력연습 : 첫 번째 필드 : %d ",$1) 
print var 
} 
$
$ awk -f ex17 data1 
100 
300 
500 
$
3. sed
sed는 stream editor의 약어이며 문자를 스트림으로 나타나는 입력을 수정하거나 편집하는데 사용되는 툴입니다. 유닉스에서 제공하는 다른 편집기와의 차이점은 원본 파일을 변경시키지 않고 명령이 실행 되는 필터 기능을 가지고 있는 것입니다. 그래서 변경된 내용을 보존하기 위해서는 적절한 조치가 필요합니다.
1)   "sed" 명령어 실행 형식
sed [-n][-e edit_command][-f command_file][ input_data_files ..] 

옵션:
-n     결과행의 출력을 하지 않는다 
-e     편집할 명령을 기술한다. 각각의 편집 명령마다 이 옵션을 붙인다 
-f     편집할 명령을 파일로 작성한 뒤 파일에서 읽어서 명령을 실행한다 
input_data_file     입력을 지정하지 않으면 표준입력으로부터 입력을 읽어 들인다.
사용 형식 예제:
$ sed -e 'sed_command' -e 'sed_command' .... filenames 
$ sed -f sed_script_file filenames 
$ cat datafile 
Hello this is kim. 
I'm so happy to meet you. 
Test sample 
sample program 
Java programming
2) 라인 선택 출력과 파일로 출력
라인을 선택하여 출력할때는 -n 옵션과 sed명령중 p 명령을 이용하여 구현할 수 있다.
$ sed -n '1,3p' datafile <-- 1번-3번라인까지 출력한다. 
Hello this is kim. 
I'm so happy to meet you. 
Test sample 
$ sed -n '/^s/p' datafile 
sample program : 라인의 시작이 's'인 라인을 출력 
$ sed '/^s/p' datafile 
Hello this is kim. 
I'm so happy to meet you. 
Test sample 
sample program 
Java programming
$ sed -e '/^sample/w sam_file' datafile 
$ cat sam_file 
sample program
3) 삭제, 추가, 삽입, 치환
삭제예: 
$ sed '1,3d 'datafile 
sample program 
Java programming 
$ sed '/^sample/,/^Java/d' datafile : 라인중 sample로 시작하는 라인 부터 Java로 시작하는 라인 까지 삭제
Hello this is kim.         
I'm so happy to meet you. 
Test sample
추가예: 
$ cat file1         : 각 라인의 아래에 '=====' 라인이 추가된다 

a 
===== 
$ sed -f file1 datafile 
Hello this is kim. 
===== 
I'm so happy to meet you. 
===== 
Test sample 
===== 
sample program 
===== 
Java programming 
=====
삽입예:             : 각 라인 위에 '***' 라인이 추가된다
$ cat file2 
i 
*** 
$ sed -f sed_script_file filenames 
*** 
Hello this is kim. 
*** 
I'm so happy to meet you. 
*** 
Test sample 
*** 
sample program 
*** 
Java programming
치환예: 
$ sed -n '1,3s/t/T/gp' datafile         :변경된 라인만 출력 
Hello This is kim. 
I'm so happy To meet you. 
TesT sample 

$ sed '1,3s/t/T/g' datafile             :모든라인을 모두 출력 
Hello This is kim. 
I'm so happy To meet you. 
TesT sample sample program 
Java programming 

$ sed -n '1,3s/t/T/gw sam_file2' datafile     : 변경된 라인만 sam_file2 파일에 저장 한다 
$ cat sam_file2 
Hello this is kim. 
I'm so happy To meet you. 
TesT sample 

$ sed 's//export/home/home3/g']
'/' 문자는 ''문자를 사용하여 표시한다. 
/export/home is user01's base directory <-- 입력라인 
/home3 is user01's base directory <- 출력라인 


[출처]
 정규식 이해 |작성자 박신양


반응형

'프로그래밍 > BASH SHELL' 카테고리의 다른 글

정규표현식  (0) 2015.01.27
쉘 문법  (0) 2015.01.27
쉘 명령 기초  (0) 2015.01.27
쉘 프로그래밍 (shell programming)  (0) 2015.01.27
쉘 프로그래밍을 연마하자 (3)  (0) 2015.01.27

댓글()

쉘 명령 기초

프로그래밍/BASH SHELL|2015. 1. 27. 10:01
반응형
 1. 쉘 내장 명령들

1) export Command
Command: export [ name [ =value ] ] ... 
Function: 지정된 names을 이후에 실행될 명령어의 환경에 자동적으로 넣기위해 사용한다. 
Examples:
$ AA=100 <- 현재 쉘에서 변수 AA에 100을 할당한다 
$ echo $AA <- 현재 쉘에서 변수 AA의 값을 출력한다 
100 
$ ksh <- 자식 쉘을 생성한다 
$ echo $AA
     <- 변수 AA의 값을 출력한다. 아무값도 출력하지 않는다
$ exit <- 다시 현재 쉘로 돌아 온다 
$ export AA <- AA 변수를 전역 변수로 설정한다 
$ ksh <- 자식 쉘을 생성한다 
$ echo $AA <- 변수 AA의 값을 출력한다 
100 <- 변수 AA의 값을 출력한다
$ 

2) readonly Command
Command: readonly [ name [ =value ] ] ... 
Function: 지정하는 변수를 읽기 전용 변수로 설정하는 명령이다. 그 변수에 값을 배정하려고 시도한다면 쉘은 에러메세지를 출력한다. readonly변수는 사용자가 변수의 값을 너무 많이 쓰지 않도록 하는데 유용하다. 또한 쉘 프로그램을 사용하는 사람들이 특수변수(예를 들면 HOME 디렉토리나 PATH)의 값을 바꿀수 없도록 하는데도 유용하며 판독 전용의 성질이 서브쉘로 전달된다. 인수가 없는 readonly는 판독 전용 변수들의 리스트를 출력한다.
Examples:
$ DB=/usr/dgk/database 
$ readonly DB 
$ DB=foo 
DB: is read-only 
$ echo $DB 
/usr/dgk/database 
$ 


3) unset Command
Command: unset [ -f ] name ... 
Function: 각각 name에 대해서 해당하는 변수 또는 함수를 제거한다. 변수 PATH, PS1, PS2, MAILCHECK, IFS와 같은 환경변수에 대해 unset을 실행할 수 없다. 

Examples: 
$ a=10 
$ set 
HOME=/home/kys 
: 
: 
TERM=vt100 
PS1=$ 
PS2=> 
: 
a=10 
$ unset a 
$ 



4) set Command
command: set -o korn_shell_mode 
Function: 사용자 환경을 설정하는 명령이다 
Options: korn_shell_mode
allexport    선언되는 모든 변수는 자동적으로 export 된다 
bgnice       우선권이 낮은 상태에서 백그라운드 작업 실행 
errexit      에러가 발생하면 exit가 실행된다 
ignoreoof    쉘을 종료하기 위해 반드시 exit명령을 실행한다 
markdirs     디렉토리명들은 / 로 표시된다 
noclobber    출력방향의 재지정시 기존 파일의 존재 여부를 체크하고난 뒤 실행하도록 지정 
noexec       명령어를 읽어 들이지만 실행 하지는 않는다 
nounset      변수값 치환시에 설정되어 있지 않은 변수는 오류로 취급한다 
trackall     실행하는 명령어들을 alias table에 등록한다 



5) eval Command
Command: eval [ arg ... ] 
Function: 쉘이 명령어 라인을 한번 해석한 후 대치와 확장을 끝내고 나서 명령어 라인을 한번 더 해석하도록할 때 사용한다. 

Examples: 
$ x = 'abc def' 
$ y = '$x' 
$ echo $y 
$x 
$ eval echo $y 
abc def 



6) exec Command
Command: exec [ command ] [ arg ... ] 
Function: exec명령을 실행하면, 그 쉘이 지시된 인수들을 가진 지정된 명령을 실행한다. 보통 명령을 실행하면 쉘은 새로운 프로세스번호를 할당받아서 실행하지만 exec는 실행시키는 쉘의 프로세스번호를 지정한 명령에게 넘겨주므로 실행이 종료되면 명령어를 실행시켰던 쉘로 돌아가지 않는다.
Examples: 
$ exec /usr/lbin/ksh <-- Replace current process with ksh 
$ 
$ exec < datafile <-- Reassign stndard input to datafile $ exec 2> /tmp/errlog 
<-- 표준에러출력전환 : 모든 에러출력은 /tmp/errlog로 
$ exec ls <-- ls를 수행하고 나면 logout 



7) trap Command
Command: trap [ action ] [ condition ... ] 
Function: 이 명령은 셀이 signals의 신호 중 하나를 수신할 때마다 명령을 실행하도록 한다. 인수가 없는 trap은 현재 설정되어 있는 trap 의 리스트를 출력한다.
trap "" signals 
signals에 있는 신호들을 수신하였을 때 그 신호는 무시된다.
trap signals 
signals에 리스트 된 각 신호들의 처리과정이 디폴트 동작으로 고정된다.
Examples: 
$ trap <-- 모든 trap과 action 을 출력한다 
$ trap '$HOME/.logout' EXIT 
<- 쉘이 EXIT 신호를 수신하여 끝나게 되면 $HOME 디렉토리에
$HOME 있는 .logout을 실행한다. 
$ trap "echo hangup >> $ERRFILE; exit " 2 
<- interrupt 신호가 수신되면 hangup를 지정한 파일에 출력하고 현행 프로세스를 종료한다
$ trap "rm $TMPFILE; exit " 1 2 15 
$ trap "" 2 
$ trap INT QUIT TERM EXIT 
-> INT QUIT TERM EXIT 의 trap을 unset한다. 각 신호의 디폴트 action으로 재설정한다 
$ trap "echo $count line processed >> $LOGFILE; exit" 1 2 15 
-> 1, 2, 15 신호중의 하나를 수신 받았을 때 count값을 $LOGFILE가 지정하는 파일로 출력
trap을 위해 사용되는 신호번호 

 신호               내 용  
1      HUP    hangup 
2      INT    interrupt 
3      QUIT   quit 
4      ILL    불법 명령어 
5      TRAP   추적 트랩 
6      IOT    IOT명령 
7      EMT    EMT명령 
8      FPE    부동소숫점 예외 
9      KILL   종료 
10     BUS    버스 에러 
11     SEGV   세그먼테이션 위반 
12     SYS    시스템 호출에 대한 불량 인수 
13     PIPE   기록한것이 없는 파이프상에서 판독 
14     ALRM   경보 클락 
15     TERM   종료(kill)로부터 소프트웨어 종료신호 
16     USR1   사용자 정의 신호1 
17     USR2   사용자 정의 신호2 
18     CLD    서브 쉘삭제
8) echo Command
Command: echo [ arg ... ] 
Function: 나열되는 아규먼트의 값들을 표준 출력으로 출력하는 명령이다. 이스케이프 문자를 사용하여 출력 특수 문자를 지정할 수 있다.
이스케이프 문자:
a Bell 문자 
b Backspace 
c 종료개행 없는 라인 
f 폼피드(formfeed) 
n Newline 
r Return 
t Tab 
Back-slash 
nnn ACSII값이 nnn인 문자 
(nnn은 0으로부터 시작하는 0-3자리의 8진수임)
Examples: 
$ echo "test escape character aaat hear me??nThanksn" 
test escape character hear me? 
Thanks 
$
9) print Command
Command: print [ -options [ n ] ] [ arg ... ] 
Function: 아규먼트 리스트를 표준 출력응로 출력하는 명령이다. 

Options: 
-      다음에 오는 모든 옵션들은 무시 
-n     라인의 끝에 개행문자를 두지 않음 
-r     echo의 이스케이프 시퀀스( ) 무시 
-R     -n 옵션외에 모든 옵션들을 무시 
-s     기록( history )화일에 args를 저장 
-un    화일 디스크립터 n에 출력 기록(디폴트 1) 
-p     |& 으로 생성된 프로세스에 출력을 기록
Ecamples: 
$ print -r 'hithere' 
hithere 
$ 
$ print 'hithere' 
hithere 
$ 
$ print -s "vi echo.c" 
vi echo.c 
$ 

10) read command
Command: read -options var1?prompt var2 . . . 
Function: 쉘이 표준입력으로 부터 라인을 읽어 들이도록하는 명령이다. 라인에서 계속적으로 공백문자로 구분된 단어들을 변수 vars에 배정하고 라인의 단어보다 변수의 수가 적으면 마지막 변수에 초과한 단어들을 전부 저장한다.
?prompt가 지정되어 있으면 지정한 prompt가 데이타를 읽어 들이기위한 프롬트로 화면이 출력된다. 리스트된 변수명이 없는 경우 읽어들인 데이타는 쉘 내장 변수인 REPLY에 저장된다.
Options:
-r     라인의 연속으로 끝에 붙어있는 을 처리하지 않는다 
-s     기록화일(history)에 입력라인을 기록 
-un    화일디스크립터 n으로부터 데이타를 읽는다(디폴트 0) 
-p     |& 으로 생성된 프로세스 출력으로 읽어들인다.
Examples: 
$ read hours mins 
10 19 
$ echo "$hours:$mins" 
10:19 
$ read file?"Which file: " 
Which file: edit.c 
$ echo $file 
edit.c 
$ 
$ read -r raw 
abcndeft 
$ echo $raw 
abcndeft 
$ read 
this is a test 
$ 
$ echo $REPLY 
this is a test 
$ cat read1 
while read -r 
do print -r "$REPLY" 
done <<! 
My Home directory is $HOME 
! 
$ 



11) ulimit Command
Command: ulimit [ -acdfmst ] [ n ] 
Functions: 쉘에서 실행하는 프로세스에 최대 한계를 정하도록 한다.
Options: 
-a     모든 한계를 디스플레이한다. 
-c     코어 덤프를 n blocks으로 제한한다. 
-d     데이타의 크기를 n Kbytes로 제한한다. 
-f     차일드 프로세스에 의해 기록될수 있는 파일의 크기를 n blocks으로 제한한다. 
-m     프로세스나 차일드 프로세스가 사용할수 있는 물리적인 메모리 크기를 n Kbytes로 제한한다. 
-s     스택영역의 크기를 n Kbytes 로 제한한다. 
-t     각 프로세스가 사용할수 있는 시간을 n seconds로 제한한다.
Examples: 
$ ulimit -f 1000 
$ ulimit -f 
1000 



12) umask Command
Command: umask [ mask ] 
Function: 사용자 화일의 생성시 permission mode를 지정한다. 디렉토리 생성시에는 777(rwxrwxrwx) 에 대한 보수값& mask 을, 화일생성시에는 666(rw-rw-rw-)에 대한 보수값& mask을 permission mode 값으로 설정한다. mask값을 설정하지 않으면 현재 설정된 umask값을 출력한다.
예제:
$ umask 022 # 디렉토리인 경우 755모드로 생성 , 화일인 경우 644모드로 생성 
$ umask 055 # 디렉토리인 경우 722모드로 생성 . 화일인 경우 622모드로 생성 
$ umask 
0055 
$ 



15) '.' , ':' Command
Command: . filename 
Function: 지정하는 filename 파일로부터 쉘 스크립트를 읽어서 현행 쉘에서 실행시킨다.
Command: : 
Function: 필수적인 널 명령이다. : 명령은 명령이 나타내는 요구를 만족시키기 위해 자주 사용된다.
Examples: 
if who | grep dgk > /dev/null 
then 
: 
else 
echo "dgk's not logged in" 
fi 



16) let Command
Command: let arg ... 
Function: let명령은 정수 연산 수식을 평가한다. 수식은 상수, 쉘변수, 그리고 연산자들을 포함할 수 있다. let은 let "expression" 또는 (( expression )) 의 형식으로 사용할 수 있다. 마지막 수식이 0값이 아니면 참, 0값이면 거짓이다. 수식안에 공백이 있으면 인용부호로 묶어서 사용한다. ( )를 이용하여 연산자의 우선 실행에 사용한다.
Examples: 
$ cat let1 
let x=x+1 y=x%4+2 
integer n=${1-20} 
while (( (n=n-1) >= 0 )) && read -r line 
do 
print -r - "$line" 
done 
$ cat let2 
let y=22*33 
let "z = y * y / (y -1)" "x = y + 1" 
if let "y % 12" 
then echo "y mod 12 != 0" 
else echo "y mod 12 == 0" 
fi 


[출처] 쉘 명령 기초 |작성자 박신양


반응형

'프로그래밍 > BASH SHELL' 카테고리의 다른 글

쉘 문법  (0) 2015.01.27
정규식 이해  (0) 2015.01.27
쉘 프로그래밍 (shell programming)  (0) 2015.01.27
쉘 프로그래밍을 연마하자 (3)  (0) 2015.01.27
쉘 프로그래밍을 연마하자 (2)  (0) 2015.01.27

댓글()

쉘 프로그래밍 (shell programming)

프로그래밍/BASH SHELL|2015. 1. 27. 10:01
반응형

unix 시스템의 사용자는 여러 개의 쉘 명령어들을 똑같은 순서로 반복해야 하는
경우가 있을 수 있다. 이런 경우 명령어들을 파일로 저장해두고 쉘 명령어처럼
사용할 수가 있는데, 이런 파일들을 쉘 script 또는 쉘 program 이라 한다. 

쉘이 쉘 program을 실행하기 위하여는 program 파일을 읽고 각 줄을 실행할 수
있어야 한다. 그래서, 해당 쉘 program 파일에 대해 read(읽기)와 execute(실행하기)
권한이 주어져야 한다. 

쉘 스크립트의 문법은 쉘의 종류에 따라 다소의 차이가 있으며, 유닉스
시스템에서 초기 구동시 참고하는 파일들이 대부분 bourne 쉘 문법으로 되어
있기에 여기서는 bourne 쉘 문법을 중심으로 전개하려 한다.

자, 그럼 sample program을 만들어 보자.
$ cat sample_pgm
  # this is sample program 
    who am i
   ls -f
$ chmod +x sample_pgm 
$ sample_pgm

위의 sample 예제는 login name을 알아보고 현재 디렉토리의 파일 목록을 출력하는
program이다.
5번째 줄에서 실행 가능하도록 execute 권한을 부여하였다. 

쉘 script의 인수(argument)


파일을 복사해 주는 cp 명령어를 생각해보면 cp 명령어 다음에 복사할 파일명과
복사될 파일명을 입력해야 한다. 
이처럼 대부분의 명령어들이 인수를 허용하는데, 쉘 script에도 인수 이용이
가능하다.


사용법을 살펴보면,
쉘 프로그램 이름  arg1 arg2 … argn

쉘 프로그램 내에서 각 인수는 $0 (program 이름), $1(arg 1), $2(arg 2)…$n(arg n)으로
참조된다.


사용예는 다음과 같다.
$ cat sample_2
 echo your program name : $0
 echo first argument : $1
 echo second argument : $2
$ chmod +x sample_2
$ sample_2 love dream
 your program name : sample 2
 first argument : love
 second argument : dream

쉘 변수 할당하기


쉘 script는 쉘 변수라는 기능을 사용하여, 보다 더 유연하게 작성될 수 있다.

쉘 변수는 문자열을 저장하는데 사용하는 하나의 이름이다. 
변수 값은 문자열이 된다. 

변수 이름 다음에 등호(=)와 변수 값을 기입함으로서 변수에 값을 줄 수
있다. 
예를 들어 bin이란 변수에 "bin"이란 값을 주려면, 
$ bin=bin
$ export bin 

두번째 줄은 bin을 지역변수에서 전역변수로 바꿔주는 명령어이다. 

쉘 명령에서 변수의 값을 참조하려면 변수명 앞에 $를 붙여 사용한다.
예를 들어, 
$ cd/usr/$bin
$ pwd
 /usr/bin

cd 명령을 실행하기 앞서 쉘은 bin이라는 변수 이름 대신 변수의 값
"bin"으로 대체한다.
결국, 
$cd/usr/bin 이라 입력한 것과 같다.

exit명령어와 return명령어


exit 명령어 
쉘 program을 종료하고 반환 code를 설정한다. 
사용법은.
exit [arg]

return 명령어 
함수의 실행을 정지하고 호출 프로시저로 돌아간다.
사용법은, 
return [arg]
호출 프로시저가 없을 경우 return 명령어는 exit와 같다.

return codes


unix의 모든 명령은 명령이 완료될 때 반환 code를 생성한다. 
명령이 정상적으로 종료되었으면 0을 return시키고 오류가 났으면 0이 아닌
값을 반환한다. 
리턴코드는 쉘 변수인 $?로 참조할 수 있다.


상용법을 살펴보면,
$ ls    
$ echo $?
 0 

쉘 변수$?은 최종적으로 return된 값을 참조한다.

$ true
$ echo $?
 0

true명령은 항상 0을 되돌려 준다. 

$ false
$ echo $?
 1

false명령은 항상 1을 반환한다.

$ cp
$ echo $?
 1

인수가 빠져 있기에 오류가 발생함.

test 명령어


test 명령어 
test 명령어는 표현식을 평가하고 반환code를 생성하는데 사용한다. 
test 명령어는 정수와 문자열과 파일의 조건을 검사하는 데에 사용될
수 있으며, 일반적으로 if문과 while문 등의 조건부 흐름 제어에
사용한다. 
사용법은,
test expression or [expression] 

표현식이 true이면 0을 return하고 false이면 0이 아닌 값을 return한다.

수식 평가
수식을 평가하는 데에의 표현식 사용법은, 
[숫자 관계 숫자]

여기서 관계는,
-lt
: less than
-le
: less than or equal to
-gt
: greater than
-ge
: greater than or equal to
-eq
: equal to
-ne
: not equal to

예를 들어 x를 3이라 가정하면,
$ [ $x -lt 7]
$ echo $?
0
$ [ $x -gt 7]
$ echo $?
1


문자열 평가
test 명령에서 문자열을 평가할 때의 표현식은,
[문자열1 = 문자열2] : 문자열이 같은 지를 평가함.
[문자열1 != 문자열2] : 문자열이 다른 지를 평가함.

예를 들어보자.
$ x=abc
$ [ $x ="abc"]
$ echo $?
 0
$ [ $x !="abc"]
$ echo $?
 1

문자열에는 반드시 ""나''부호를 사용해야 한다.
문자열 연산자에는, 
-z 문자열
: 문자열의 길이가 0이면 참
-n 문자열
: 문자열의 길이가 0이 아니면 참


파일 평가
test 문에서 파일이 디렉토리인지 파일인지를 평가할 수 있다.
사용법은, 
test -Option filename

여기서 Option은,
-f
: filename이 파일이면 참.
-d
: filename이 디렉토리이면 참.
-s
: 파일이 존재하며 크기가 0보다 크면 참.
-r
: 파일이 존재하며 읽기 가능하면 참.
-w
: 파일이 존재하며 쓰기 가능하면 참.
-x
: 파일이 존재하며 실행 가능하면 참.


다른 연산자
test 명령어에서 다음의 연산자를 사용하면 복수 검사가 가능하다.
  
-o
: or
-a
: and
!
: not
\(\)
: grouping

예를 들어,
$ test -s filename -a -r filename 

파일이 존재하고 size가 0보다 크며 그리고(and) 읽기 가능한지를
검사함. 

산술식 표현


본격적으로 반복문을 시작하기 전에, 쉘 script에서의 산술식 표현 방법을
알아보자.
산술식 표현 방법은,
let expression or ((expression))

예를 들어보자.
$ x=10
$ y=2
$ ((x=x+2))
$ echo $x
 12


쉘 script에서의 산술식은 
let 명령을 사용하거나, 
괄호를 두 개 사용하여 표현하거나
expr 명령어를 이용한다.
예를 들어보자.
$ let x=x+6
$ echo $x
  18
$ let "x=x/(y+1)"
$ echo $x
  6

산술식 표현 속에 괄호는 평가 순서를 바꾸는 데 사용될 수 있다. 
이런 경우 큰 따옴표를 써야함을 유의하자.
위의 형식에 대한 바른 표현은, 
let "x=x/(y+1)"또는 ((x=x/(y+1))) 또는 x=`expr $x/($y+1)`
[참고] ` (back qoute)
expr 을 사용한 예를 더 살펴보자.
$ expr 30 "*" 30
 900

if 문


if 문은 program을 조건에 따라 분기시킨다.


사용법을 살펴보면,
 if
  list a
 then
  list b 
 fi



사용예는 다음과 같다.
 if
  test -s funfile
 then
  echo funfile exists
 fi

funfile이 존재하고 크기가 0이 아니면 "funfile exists"라는 message를 화면에
뿌린다.

반복문 (loop문)


반복문은 일련의 명령을 반복할 수 있게 한다. 
반복을 계속할 지는 키 명령의 반환 코드에 기초하여 이루어진다.
if 문이나 case 문은 key word로 시작되고 거꾸로 된 key word로 끝나는 반면
반복문은 키워드와 어떤 조건으로 시작하고 내부는 do/done으로 둘러
쌓이게 된다.
반복문은 아래의 3가지 형태이다.
while 문
  while…
  do
 done
until 문
 until…
  do
 done
for 문
 for…
  do
 done

while 문


while 문은 조건이 참인 동안은 loop를 반복한다.


사용법을 살펴보면,
 while
  list a
 do
  list b
 done



사용예[1]은 다음과 같다
 $cat sample_while
 x=1
 while((x<=10))
 do
  echo x is $x
  let x=x+1
 done
 $sample_while
  x is 1
  x is 2
   ?BR>    ?BR>    ? 
  x is 10

위의 예에서 알 수 있듯이 조건식인 ((x<=10))이 참인 동안은 loop 내부를 반복하게
된다. 그래서, 무한 loop에 빠지지 않아야 함을 주의하자.


사용예[2]는 다음과 같다
$ cat sample_while2 
  ans=yes
  while
  [ $ans = "yes" ]
 do
  echo enter a name
  read name
  echo yes or no
  read ans
 done
$ chmod 777 sample_while2
$ sample_while2

until 문


until 문은 조건식이 참이 될 때까지 loop를 반복한다.
(비교 : while 문은 조건이 참인 동안 loop가 계속된다.) 


사용법을 살펴보면, 
 until
  list a
 do
  list b
 done



사용예는 다음과 같다.
$ cat sample_until
  x=1
  until((x>10))
 do
  echo x is $x
  let x=x+1
 done
$ sample_until
  x is 1
  x is 2
   ?BR>    ?BR>    ?BR>   x is 10

위의 예에서 알 수 있듯이 until 문은 조건이 참이 될 때 까지 반복된다.

for 문


for 문은 list에 있는 각 item들이 for 반복문에 순차적으로 할당되어 소진될 때 까지
loop를 실행한다.


사용법을 살펴보면, 
 for var list
 do
  list
 done



사용예는 다음과 같다.
$ cat sample_for
 for x in 1 2 3 4 5
 do
  echo " 2 * $x is \c"
  let x=x=+2
 echo $x
 done
$ sample_for
  2*1 is 2
  2*2 is 4
    ?BR>     ?BR>     ?BR>   2*5 is 10

break, continue, exit


반복문에서 loop를 중단시킬 필요가 있을 때가 있을 수 있다. 
break 와 continue 는 무조건적인 흐름 제어를 제공한다.

exit 
전체 프로그램이 종료되어야 할 경우 사용한다. 
프로그램을 완전히 종료하고 쉘 프롬프트로 나가게 한다.

break 
loop 를 종료하고 done 다음의 명령을 계속하여 수행하도록 한다. 

continue 
loop 의 나머지 명령을 중단하고 loop 의 맨 위로 가게 한다. 

즉, continue는 단지 한번의 loop를 종료하고 loop의 맨 위에서 loop를 계속하게
하며, break는 loop를 빠져나가 다음 단계를 계속 수행하게 한다. 


사용예는 다음과 같다.
$ cat sample_break
 while
  true
 do
  echo "enter file name to remove :\c"
  read file
  if test ! -f $file
  then
   cho $file is not a require file
   continue
  fi
  echo removing $ file
  rm $file
  break
 done 



반응형

'프로그래밍 > BASH SHELL' 카테고리의 다른 글

정규식 이해  (0) 2015.01.27
쉘 명령 기초  (0) 2015.01.27
쉘 프로그래밍을 연마하자 (3)  (0) 2015.01.27
쉘 프로그래밍을 연마하자 (2)  (0) 2015.01.27
쉘 프로그래밍을 연마하자 (1)  (0) 2015.01.27

댓글()

쉘 프로그래밍을 연마하자 (3)

프로그래밍/BASH SHELL|2015. 1. 27. 10:00
반응형

[ 쉘 프로그래밍을 연마하자 (3) ] 


이번 강좌에서는 분기문에 대해서 배워보도록 하자. 본쉘에서의 분기문은 C언어와 비슷한 면도 있고 약간 다른것도 있지만 대체적으로 그 사용법이 간결하여 배우기가 쉽다. 그러면 하나하나 익혀보자. 


* for 문

형식:

for 변수 in list1 list2 list3
do
명령어들
done

C언어의 for와는 많이 다른 형태의 for문이다. in 뒤에 나오는 원소를 변수에 대입시킨다. 그리고 그 원소들의 개수만큼 반복되어 do 뒤에 나오는 명령어들을 실행한다. 직접 프로그래밍해 보는것이 제일 쉽게 이해될 듯 하다. 

----[예제4] for.sh ----------------------------

#!/bin/sh

for A in 1 2 3 4 5
do
echo $A
done

-----------------------------------------------

설명이 잘 이해가 되지 않아도 소스 몇 줄로 쉽게 이해가 되었을 것으로 믿는다. 예제4를 조금 더 응용해 보자. 

----[예제4-1] pid.sh ----------------------------

#!/bin/sh

for A in `ps -aux | cut -c10-15`
do
echo $A
done

-------------------------------------------------

예제4-1은 현재 떠있는 모든 프로세스의 번호를 보여주는 쉘 스크립트 이다. 좀 더 유용한 스크립트 하나를 더 예로 들어보자. 

----[예제4-2] change.sh --------------------------

#!/bin/sh

for A in *
do
mv $A `echo $A | tr [A-Z] [a-z]`
done

--------------------------------------------------

이 스크립트를 실행시키면 현재 디렉토리에 있는 모든 대문자화일을 소문자로 바꿔 준다. in 뒤에 그냥 * 표시를 써주면 현재 디렉토리에 있는 모든 화일들을 원소로 쓰게 된다. 단 .으로 시작하는 화일은 포함되지 않는다. 그것을 tr 명령어를 이용해 하나하나 대문자를 소문 자로 바꿔주게 되고, 그것을 mv 명령어를 이용해 파일이름을 바꾸는 것이다. 


* while 문


형식:

while 조건문
do
명령어들
done

while문은 C언어의 그것과 일치한다. 별 다른 설명 필요없이 예제를 보도록 하자. 

----[예제5] while.sh ---------------------------

#!/bin/sh

haha=1
while [ $haha -lt 10 ]
do
echo "Puhaha~"
haha=`expr $haha + 1`
done

------------------------------------------------

haha란 변수에 1을 대입하고 , 그것이 10 보다 작을 동안에 계속 루프 를 돌게 된다. 본쉘에서 숫자 계산을 할때는 expr명령어를 사용해야 한다. 


* until 문

형식:

until 조건문
do
명령어들
done

while 문과는 반대로 조건문이 참이면 루프를 끝낸다. 

----[예제6] until.sh ---------------------------

#!/bin/sh

until who | grep errai
do
sleep 5
done
echo -e "a--COME BACK errai!--"

------------------------------------------------

who명령어를 통해 현 계정 접속자를 검색하여 그중 errai란 사용자가 있다면 루프를 종료하고 문장을 출력시키는 스크립트이다.

while이나 until문을 돌릴 경우 조건문의 값이 0 보다크다면 항상 참값이 되어 무한루프를 돌게 된다. 그때 사용되는 명령어가 continue 와 break이다. 둘다 C언어의 그것과 용도가 같다. 루프문의 수행도중 continue를 만나면 그 이하의 내용은 모두 생략하고 다시 조건검사로 돌아가게 되고 break는 루프문을 강제로 빠져 나올때 사용하게 된다. 

----[예제6-1] stupid.sh --------------------------

#!/bin/sh

while [ 1 ]
do
echo -n "리눅스가 좋아?(예/아니오) : "
read a
if [ x$a = "x예" ]
then
break
else
continue
fi
done
echo "GOOD!"

-------------------------------------------------

금방 이해가 되었을 것이라 믿는다. 한가지만 말하자면 if 문의 조건식에서 그냥 $a = "예" 라고 하면 될 것을 각각 앞에 x자를 붙인 것이 보이는데 이것은 $a에 아무런 값도 대입하지 않았을때 에러가 나는 것을 막기 위함 이다. 한번 x를 없애고 실행시켜 보기 바란다. 


* case 문


형식:

case 변수 in
패턴1 | 패턴2 .... ) 명령어들;;
*) 명령어들;;
esac

변수값에 따라 다른 명령어를 수행해야 할 때 유용한 명령어이다. C언어의 그것과 유사하다. 

----[예제7] vowel.sh ---------------------------

#!/bin/sh

echo -n "what is your favorite food? "
read answer
a="a"
case "$answer" in
a* | e* | i* | o* | u* ) a="an";;
esac

echo You like $a $answer!

-----------------------------------------------

영단어를 입력받아 단어가 모음으로 시작되느냐 자음으로 시작 되느냐에 따라 관사 an 혹은 a를 붙여주는 스크립트이다.
다음에는 c 쉘에 관해 공부해 보도록 하겠다.



반응형

'프로그래밍 > BASH SHELL' 카테고리의 다른 글

정규식 이해  (0) 2015.01.27
쉘 명령 기초  (0) 2015.01.27
쉘 프로그래밍 (shell programming)  (0) 2015.01.27
쉘 프로그래밍을 연마하자 (2)  (0) 2015.01.27
쉘 프로그래밍을 연마하자 (1)  (0) 2015.01.27

댓글()