검색 엔진의 방문이 늘어나고 있군...

Posted
Filed under 쉘 스크립트
참조 원문 : How to Run Scripts at Ubuntu Startup

  우분투로 부팅할 때 어떤 스크립트를 실행시키게 만드는 일은 레드햇 기반의 리눅스에 비해 어려운 편인데 그 이유는 우분투가 전통적인 Sys-V Init 스크립트 방식 대신 진일보적인 업스타트라는 방식을 메인으로 사용하기 때문입니다. 지금으로서 우분투에서 부팅 시 스크립트를 돌리는 방법으로는 총 세 가지가 있습니다.(업스타트에 대한 자세한 설명은 없군요.)

1. Upstart 방식
  /etc/init.d 디렉토리에는 '업스타트 방식을 지원하는 프로그램들의 업스타트 스크립트에 대한 링크'가 전통적인 Sys-V Init 스크립트와 함께 공존하고 있습니다. 예를 들어 아래 중 apache2는 업스타트 방식을 사용하지 않지만 vsftpd는 업스타트를 사용한다는 것을 볼 수 있습니다.
ls -l /etc/init.dtotal 180
-rwxr-xr-x 1 root root 7476 2011-02-22 11:32 apache2
lrwxrwxrwx 1 root root 21 2011-05-21 04:37 vsftpd -> /lib/init/upstart-job

2. 하위호환을 위한 System-V 방식
  우분투가 업스타트를 사용하긴 하지만 많은 프로그램들이 업스타트를 지원하지 않는 탓에 여전히 Sys-V 방식을 지원합니다. 당연히 활용 방식은 다른 레드햇 기반과 동일합니다. 먼저 /etc/init.d 디렉토리 안에 스크립트를 집어넣고 아래와 같은 명령어로 해당 스크립트의 퍼미션을 변경합니다.
chmod 755 myscript
    그 후 원하는 런레벨에 해당하는 디렉토리 안에 심볼릭 링크를 만들어 해당 스크립트에 연결시킵니다. 예를 들어 위 스크립트를 런레벨2(우분투의 디폴트 런레벨로 그래픽 부팅에 해당)에서 실행되게 하려면 /etc/rc2.d 디렉토리 안에 심볼릭 링크를 만들면 됩니다. 역시 다른 리눅스와 마찬가지로 심볼릭 링크의 파일명에서 첫 글자를 S로 하고 그 뒤에 실행 순서용 숫자를 적어줍니다. 높은 숫자일수록 늦게 실행되죠.
ln -s /etc/init.d/myscript /etc/rc3.d/S99myscript
  팁으로 아래 프로그램을 설치 및 실행하여 위 작업을 더 편하게 할 수 있습니다. 물론 설치와 실행 모두 root 권한이 필요합니다.
sudo apt-get install sysv-rc-conf

3. rc.local 파일 사용
  가장 원시적인 방법으로서 /etc/rc.local 파일 안에 실행하고 싶은 명령어를 집어넣으면 2~5 런레벨일 때 해당 명령어를 실행합니다. 디폴트로 주석과 마지막 줄의 exit 0 빼고는 비어있습니다.

2013/06/17 15:01 2013/06/17 15:01
Posted
Filed under 쉘 스크립트
가끔 스크립트에서 CPU 사용률을 구해야 할 때가 있습니다. 예를 들어 CPU 사용률을 측정하기 위한 Nagios 플러그인 같은 걸 만들어야 할 때가 있죠. 그럴 때 유용하게 쓸 수 있는 간단한 스크립트입니다.
#!/bin/bash

$INTERVAL_SEC=1
$NUM_REPORT=3

CPU_REPORT=`vmstat -n $INTERVAL_SEC $NUM_REPORT | tail -$NUM_REPORT | awk 'BEGIN{USER=0;SYS=0;WAIT=0;IDLE=0} {USER=USER+$13;SYS=SYS+$14;WAIT=WAIT+$16;IDLE=IDLE+$15} END{print USER/'$NUM_REPORT'" "SYS/'$NUM_REPORT'" "WAIT/'$NUM_REPORT'" "IDLE/'$NUM_REPORT'}'`

CPU_USER=`echo $CPU_REPORT | awk '{ print $1 }' | cut -d "." -f 1`
CPU_SYSTEM=`echo $CPU_REPORT | awk '{ print $2 }' | cut -d "." -f 1`
CPU_IOWAIT=`echo $CPU_REPORT | awk '{ print $3 }' | cut -d "." -f 1`
CPU_IDLE=`echo $CPU_REPORT | awk '{ print $4 }' | cut -d "." -f 1`
  INTERVAL_SEC는 조사 시간 간격이고 NUM_REPORT는 조사 횟수입니다. 즉, 디폴트 값으로 1초당 1번씩 총 3번 사용률을 구한 후 평균값을 구하는 겁니다. 결과로 얻을 수 있는 정보는 사용자, 시스템, 입출력에 의한 CPU 사용률과 IDLE입니다. 사실 훨씬 간단하게 구할 수도 있지만 다수의 결과에서 평균값을 구하는 것이 더 정확한 것으로 보여 이렇게 작성했습니다.

  참고로 밑에 cut을 이용해 소수점 이하의 값을 잘라버린 이유는 나중에 스크립트 내에서 if 문을 통해 비교를 할 경우 정수가 필요하기 때문입니다. 따라서 그냥 출력만 하려고 할 경우 해당 부분은 없어도 됩니다. 하지만 그럴 경우 '1.33333' 같이 나눠 떨어지지 않는 값이 나올 수도 있으므로 결국 그에 대한 적절한 처리가 필요할 것입니다.

  만약 리눅스가 아닌 유닉스에서 사용하려면 USER, SYS, WAIT, IDLE이 있는 위치(차례대로 각각 $13, $14, $16, $15)를 해당 OS의 vmstat 출력 결과에 맞게 수정해야 합니다. 또한 vmstat 명령어의 옵션을 약간 수정해야 할 수도 있습니다.

2011/07/15 14:48 2011/07/15 14:48
Posted
Filed under 쉘 스크립트
모니터링에 유용'할지도 모르는' 쉘 스크립트 2개를 소개합니다. 하나는 제가 만들었고 나머지 하나는 어디선가 납치했습니다.


1. 일정 시간마다 특정 이름의 프로세스들 중 CPU 점유율이 지정한 수치 이상인 프로세스 킬

  예를 들어 '매 60초마다 아파치(httpd) 프로세스 중 CPU 점유율이 40% 이상인 프로세스'를 찾아 죽이는 일을 할 수 있습니다. 약간 허접하게 만들어서 처음 검사할 때 걸려나온 프로세스들을 죽이지 않고 죽이기 직전에 다시 검사해서 나온 놈들을 죽입니다. 딱히 처음 나온 프로세스들의 PID를 변수에 저장해서 죽일 정도로 정교하게 처리할 필요가 없어 보여서 대충 그렇게 만들었습니다는 훼이크고 능력 부족으로;; 제거 대상을 파일로 리다이렉션해서 이리저리 처리할 수는 있을 거 같긴 한데 그렇게까지 할 필요는 없을 거 같습니다. 또 검사해서 괜찮으면 안 죽이면 그만이죠 뭐.
#!/bin/sh

KillingInterval=60
ThresholdToKill=40
KillingTarget=httpd

clear
while :
do
TargetCount=`ps -ef | grep -v grep | grep $KillingTarget | awk '$4>='$ThresholdToKill | wc -l`
date
if [ $TargetCount -gt 0 ]
then
echo "***점유율 $ThresholdToKill % 이상 프로세스 발생. 아래 프로세스에 대하여 제거 실시***"
ps -ef | grep -v grep | grep $KillingTarget | awk '$4>='$ThresholdToKill
ps -ef | grep -v grep | grep $KillingTarget | awk '$4>='$ThresholdToKill | awk '{print $2}' | xargs kill -9
else
echo "점유율 $ThresholdToKill % 이상 프로세스 없음"
fi
echo
sleep $KillingInterval
done


2. 특정 이름을 가진 프로세스의 개수와 지난 1분간 프로세스 큐 부하율의 평균 값 모니터링

  특정 이름을 가진 프로세스들의 개수가 지정한 수보다 적게 존재하는지와 uptime이나 top에서 확인이 가능한 지난 1분간 프로세스 큐 부하율의 평균 값이 지정한 값보다 높은지를 모니터링하는 스크립트입니다.

  AIX를 기준으로 만들어졌으며 시스템의 로케일에 따라 awk의 칼럼 값을 수정해야 할 수도 있습니다. 또한 OS에 따라 banner 명령어 부분을 수정해야 할 수도 있으며, echo에서 이스케이프(\c, \007)가 안 먹힐 경우에도 수정이 필요합니다.
#!/bin/sh

TargetProcess=httpd
ThresholdLoad=20
MinimumNumber=60
CheckInterval=5
ProcessNumber=`ps -ef | grep $TargetProcess | grep -v grep | wc -l`
LoadFloat=`uptime |sed s/hrs,//| sed s/mins,// | awk '{print $10}' | cut -f1 -d,`
LoadInteger=`echo $LoadFloat | cut -f1 -d.`

while :
do
echo "\n`hostname` : \c"
date
banner `echo ${ProcessNumber}/${MinimumNumber}-${LoadFloat}`

if [ $LoadInteger -ge $ThresholdLoad -o $ProcessNumber -lt $MinimumNumber ]
then
echo "  *** Check the process or system load *** \007 \c "
else
echo "  OK ------------------------------------------------ \c"
fi

sleep $CheckInterval
done
2011/01/30 17:25 2011/01/30 17:25
Posted
Filed under 쉘 스크립트
참조 원문 : 6 Tricks with awk
관련 글 : awk 기초, awk를 이용한 검색, awk에서 변수 사용

  AWK는 텍스트 기반의 데이터(파일이나 데이터 스트림)를 처리하기 위한 프로그래밍 언어입니다. 주로 문자열 데이터타입, 배열, 정규 표현식을 사용합니다.

  AWK는 본 쉘과 더불어 표준 유닉스 환경에서 사용할 수 있는 스크립트 언어이며 LSB(Linux Standard Base) 사양서에 반듯이 있어야 하는 것으로 규정된 명령어 중 하나입니다.

  비록 AWK가 1줄 프로그래밍을 지원하고 또 대부분 그렇게 사용되지만 하나의 완벽한 프로그램을 짜는 것도 가능합니다.


1. 파일에서 정렬 없이 중복 내용 삭제
  정렬을 하지 않고도 중복된 내용을 찾아 지우고 다른 파일로 리다이렉트하는 방법입니다.
awk '!x[$0]++'
  그리고 아래는 그 예와 결과입니다.
$ echo -e "aaa\nbbb\naaa\naa\nccc\naa"|awk \!'x[$0]++'
aaa
bbb
aa
ccc

2. 특정 파일 그룹의 총 용량 합산
  아래는 디렉토리 내에 모든 파일의 크기를 합산하는 방법입니다.
ls -l | awk '{s = s+$5 }; END { print s }'
  그리고 아래는 현재 디렉토리와 서브디렉토리 내에 있는 .mp3 파일들의 용량을 합산하는 방법입니다.
ls -lR |grep .mp3 | awk '{s = s+$5 }; END { print s }'

3. find 명령어와 연계
  아래는 find로 컴퓨터 내의 모든 .mp3 파일들을 찾아 위에서 본 것과 비슷한 방식으로 용량을 합산하는 방법입니다.
find / -name "*.mp3" -exec ls -l {} \; | awk '{s = s+$5 }; END { print s }'

4. 사용횟수로 기준으로 내림차순으로 정렬하여 히스토리 출력
history | awk '{a[$'`echo "1 2 $HISTTIMEFORMAT" | wc -w`']++}END{for(i in a){print a[i] "\t" i}}' | sort -rn | head

5. AWK 필드 분석
  각 줄마다 번호를 매기고 다시 각 줄의 아래에 해당 줄에 있는 필드마다 번호를 매겨 출력합니다.
awk '{print NR": "$0; for(i=1;i<=NF;++i)print "\t"i": "$i}'

6. 여러 파일의 파일명을 한 번에 변경
  아래는 특정 파일들의 파일명 끝에 '.new'를 붙이는 방법입니다. 앞 부분의 'ls -al pattern'을 변경하여 다양한 활용이 가능합니다.
ls -1 pattern | awk '{print "mv "$1" "$1".new"}' | sh
2011/01/19 10:27 2011/01/19 10:27
Posted
Filed under 쉘 스크립트
참조 원문 : Back up MySQL Databases with a Simple Bash Script
관련 글 : mysqldump로 MySQL DB 백업하기

  LPIC 공부한다는 변명하에 와일드 플래닛에 빠져 살아 포스팅이 사라진 요즘 날로 포스팅할 꺼리가 보여서 낼름 주워먹으러 왔습니다. MySQL DB를 백업하는 간단명료한 스크립트입니다.
NOW=`date +"%Y-%m"`;
BACKUPDIR="location/of/your/backup/dir/$NOW";

### Server Setup ###
#* MySQL login user name *#
MUSER="user";

#* MySQL login PASSWORD name *#
MPASS="pass";

#* MySQL login HOST name *#
MHOST="your-mysql-ip";
MPORT="your-mysql-port";

# DO NOT BACKUP these databases
IGNOREDB="
information_schema
mysql
test
"

#* MySQL binaries *#
MYSQL=`which mysql`;
MYSQLDUMP=`which mysqldump`;
GZIP=`which gzip`;

# assuming that /nas is mounted via /etc/fstab
if [ ! -d $BACKUPDIR ]; then
  mkdir -p $BACKUPDIR
else
 :
fi

# get all database listing
DBS="$(mysql -u $MUSER -p$MPASS -h $MHOST -P $MPORT -Bse 'show databases')"

# SET DATE AND TIME FOR THE FILE
NOW=`date +"d%dh%Hm%Ms%S"`; # day-hour-minute-sec format
# start to dump database one by one
for db in $DBS
do
        DUMP="yes";
        if [ "$IGNOREDB" != "" ]; then
                for i in $IGNOREDB # Store all value of $IGNOREDB ON i
                do
                        if [ "$db" == "$i" ]; then # If result of $DBS(db) is equal to $IGNOREDB(i) then
                                DUMP="NO";         # SET value of DUMP to "no"
                                #echo "$i database is being ignored!";
                        fi
                done
        fi

        if [ "$DUMP" == "yes" ]; then # If value of DUMP is "yes" then backup database
                FILE="$BACKUPDIR/$NOW-$db.gz";
                echo "BACKING UP $db";
                $MYSQLDUMP --add-drop-database --opt --lock-all-tables -u $MUSER -p$MPASS -h $MHOST -P $MPORT $db | gzip > $FILE
        fi
done
  몇몇 변수를 고쳐주면 바로 사용할 수 있으며 변수명과 내용은 아래와 같습니다.
  • BACKUPDIR : 백업을 저장할 디렉토리
  • MUSER : MySQL 유저
  • MPASS : MySQL 유저 패스워드
  • MHOST : MySQL 서버의 IP 주소나 도메인명(예: localhost)
  • MPORT : MySQL 포트(디폴트: 3306)
  이제 스크립트 파일에 실행 권한을 줍니다. 또한 파일 안에 패스워드가 있으므로 아무나 읽지 못하게 읽기 권한을 적절히 설정합니다. 이제 필요할 때 수동으로 실행하거나 crontab을 이용하여 정기적으로 실행하면 됩니다. 예를 들어 매일 자동으로 백업을 하게 하려면 'crontab -e'를 실행하여 아래의 내용을 추가합니다.
@daily /스크립트/경로/스크립트명.sh
  만약 DB가 크다면 max_packet_size의 디폴트 값이 문제가 되어 실행에 실패할 수도 있는데 그럴 경우에는 mysqldump 명령어 부분에 아래와 같은 옵션을 추가하면 됩니다.
--max_allowed_packet=500M
2011/01/17 15:59 2011/01/17 15:59
Posted
Filed under 쉘 스크립트
참조 원문 : Recording User Activity with a Script

  'script'라는 명령어는 터미널 세션에 출력되는 모든 글자를 파일에 기록하는 기능을 가지고 있습니다. 이를 스크립트에 이용하여 사용자의 활동을 로그로 남기는 딱히 쓸모없어 보이지만 흥미로운 글을 발견하여 포스팅합니다.
#!/bin/bash
# Capture keystrokes of a user and log

TIMESTAMP=$(date +%m%d%y%H%M%S)
HOST=$(hostname|cut -f1 -d.)
LOGDIR=/var/log/user
LOGFILE=${HOST}.${LOGNAME}.${TIMESTAMP}
touch $LOGDIR/$LOGFILE

chown $LOGNAME ${LOGDIR}/${LOGFILE}
chmod 600 ${LOGDIR}/${LOGFILE}

script ${LOGDIR}/${LOGFILE}
chmod 400 ${LOGDIR}/${LOGFILE}
  위 스크립트는 호스트명, 사용자명, 타임스탬프로 /var/log/user 디렉토리 안에 로그 파일을 만들어 기록하게 만듭니다. 정확히는 적당한 경로에 적당한 이름으로 파일을 만들어 퍼미션을 조정하는 것 뿐이고 정작 중요한 기록은 script 명령어가 다 합니다. 참고로 /var/log/user라는 디렉토리는 기본적으로 없기 때문에 스크립트를 사용하기 전에 미리 만들어야 합니다.

  위 스크립트를 적당한 위치에 적당한 이름으로 놓고 활동을 로깅할 사용자의 홈 디렉토리에 있는 .bash_profile이나 .profile에서 위 스크립트를 실행하도록 만들면 됩니다. 만약 모든 사용자에 대해 위 스크립트를 적용하고 싶다면 /etc/profile 파일에서 위 스크립트를 실행하게 만들면 됩니다.


2011/01/05 10:05 2011/01/05 10:05
Posted
Filed under 쉘 스크립트
참조 원문 : 8 More Bash Tips for Working Faster With the Shell

  날이면 날마다 오는 배시 관련 포스팅입니다.

앨리어스 등록
  일반적으로 앨리어스를 등록할 때는 ~./bashrc 파일에 아래와 같은 형식으로 원하는 내용을 집어넣습니다.
alias name='command'
  그냥 이렇게 평범하게 등록하고 쓰는 방법도 있지만 앨리어스 전용 파일을 별도로 만들고 그 파일을 읽는다면 관리가 더 깔끔하겠죠? 이를 위해 .bash_aliases 파일을 만들어 앨리어스들을 넣은 후 ~./bashrc 파일에서 아래와 같이 파일을 읽어들입니다.
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

히스토리를 탐색할 때 페이지 업/다운 키 사용
  ~/.inputrc라는 파일을 만들고 아래의 두 줄을 집어넣으면 PageUp 키와 PageDown 키로 히스토리를 탐색할 수 있습니다. 파일을 만든 후 다시 로그인을 해야 적용됩니다.
"\e[5~": history-search-backward
"\e[6~": history-search-forward

이맥스 스타일의 단축키들
  화살표까지 손을 옮기기 귀찮을 때 사용하면 편합니다.
  • ^A – go to the start of line
  • ^E – go to the end of line
  • ^H – erase one character to the left
  • ^D – erase one character to the right, it also exits the shell by default if there is no character to delete
  • ^U – erase everything from the cursor to start
  • ^K – erase everything from the cursor to end
  • ^P – bring the previous command in history
  • ^N – bring the next command in history
  • ^C – interrupt character, sends SIGTERM to the current application

매뉴얼 페이지에 색깔 적용
  아래의 내용을 ~./bashrc 파일에 넣습니다.
export LESS_TERMCAP_mb=$'\E[01;31m' # begin blinking
export LESS_TERMCAP_md=$'\E[01;38;5;74m' # begin bold
export LESS_TERMCAP_me=$'\E[0m' # end mode
export LESS_TERMCAP_se=$'\E[0m' # end standout-mode
export LESS_TERMCAP_so=$'\E[38;5;246m' # begin standout-mode - info box
export LESS_TERMCAP_ue=$'\E[0m' # end underline
export LESS_TERMCAP_us=$'\E[04;38;5;146m' # begin underline
  그리고 .bashrc 파일을 다시 읽어들입니다.
. ~/.bashrc


파일 이름의 뒷부분에 원하는 문자열 추가
  만약 'filename'이란 이름의 파일이 있을 때 이 파일을 백업 파일로 만들 때는 'filename.backup' 같은 식으로 이름을 바꾸기 마련입니다. 이때 보통 아래와 같은 방법으로 이름을 바꿉니다.
mv filename filename.backup
  이때 아래의 형식으로 명령을 내리면 같은 효과를 볼 수 있습니다.
mv filename{,.backup}
2010/12/29 13:44 2010/12/29 13:44
Posted
Filed under 쉘 스크립트
참조 원문 : HowTo: Use Bash Parameter Substitution Like A Pro

  달러($) 문자는 파라미터 확장과 명령어 대입에 사용됩니다. 이걸 이용하면 sed나 awk 같은 외부 명령어 없이 필요에 따라 변수를 조작하거나 확장할 수 있습니다.


more..


more..


more..


more..


more..


more..


more..



요약: 문자열 조작과 확장 변수
  • ${parameter:-defaultValue} : 디폴트 쉘 변수 값을 사용
  • ${parameter:=defaultValue} : 디폴트 쉘 변수 값을 설정
  • ${parameter:?"Error Message"} : 파라미터가 설정되어 있지 않았을 경우 에러 메시지 출력
  • ${#var} : 문자열의 길이 계산
  • ${var%pattern} : 오른쪽에서 패턴과 일치하는 부분 제거
  • ${var%%pattern} : 패턴과 일치하는 부분들 중 가장 왼쪽 부분부터 끝까지 제거
  • ${var:num1:num2} : 문자열 추출
  • ${var#pattern} : 왼쪽에서 패턴과 일치하는 부분 제거
  • ${var##pattern} : 패턴과 일치하는 부분들 중 가장 오른쪽 부분부터 처음까지 제거
  • ${var/pattern/string} : 검색 및 치환(1개)
  • ${var//pattern/string} : 검색 및 치환(모두)
2010/12/21 09:53 2010/12/21 09:53
Posted
Filed under 쉘 스크립트
참조 원문 : Using Variables With awk
관련 글 : awk 기초, awk를 이용한 검색, 6가지 awk 트릭

  awk는 내장된 변수와 유저 정의 변수를 지원하며 bash 스크립트 같은 것과 달리 사용하기 전에 미리 선언할 필요가 없습니다. 변수의 종류로는 다음의 3가지가 있습니다.
  1. 시스템 변수(=내장 변수)
  2. 일반(Scalar) 변수
  3. 배열 변수

1. 시스템 변수
  시스템 변수는 대문자로 되어 있으므로 대소문자를 주의하여 사용해야 합니다.

NR: 줄 번호(number of input lines)
  NR 변수는 매 레코드를 읽을 때마다 값이 1씩 증가하는 변수입니다.
$ awk '{print NR}' processes
1
2
3
...생략...
72
73
74

NF: 필드 번호(number of fields)
  각 레코드에는 공백 문자로 구분되는 필드들이 있습니다. 필드의 개수는 레코드에 따라 다를 수 있습니다.
$ awk '{print NF}' processes
11
12
  아래는 각 레코드마다 1,2번째 필드의 내용과 총 필드의 개수를 출력하는 예입니다.
$ awk '{print $1,$2,NF}' /var/log/messages.1
Jul 24 14
Jul 24 11
Jul 24 8
Jul 24 12

FILENAME: 입력 파일 이름(name of input file)
  현재 처리 중인 파일의 이름이 담겨 있습니다. 이 변수는 BODY 섹션 이전에는 선언되지 않기 때문에 BEGIN 섹션에서는 사용할 수 없습니다.

FNR: 입력 파일들 중 현재 사용 중인 파일(used with multiple input files)
  NR과 마찬가지로 줄(레코드)번호를 뜻하지만 NR이 모든 입력 스트림을 통틀어 계산한 줄번호를 출력하는 것과 달리 FNR은 현재 처리 중인 파일 내의 줄번호를 출력합니다.

FS: 필드 구분 문자(field separator character)
  기본적으로 필드는 공백이나 탭으로 구분하지만 "-F" 옵션 뒤에 문자를 적어 해당 문자를 필드 구분 문자로 사용할 수 있습니다. 아래는 ':' 문자로 필드를 구분하는 /etc/passwd 파일에서 'jane'이라는 문자열을 찾아 첫 번째 필드와 네 번째 필드를 출력하는 예입니다.
$ tail /etc/passwd | awk -F: '/jane/{print $1, "Group: "$4}'
jane Group: 502
구분 문자를 여러 개 사용하고 싶다면 정규식을 사용하여 목적을 달성할 수 있습니다. 아래는 공백, 콜론, 탭을 구분 문자로 사용한 모습입니다. 참고로 이스케이프 문자가 하나 있으므로(\t) 싱글 쿼트가 필요합니다.
$ tail /etc/passwd | awk -F'[ :\t]' '/jane/{print $1, "Group: "$4}'

OFS: 출력용 필드 구분 문자(output field separator)
  출력에 사용하는 필드 구분 문자는 기본적으로 공백입니다. 아래처럼 각 필드 사이에 콤마를 사용하면 출력용 필드 구분 문자인 공백이 출력됩니다.
$ tail /etc/passwd | awk -F'[ :\t]' '/jane/{print $1,$2,$3,$4,$6,$7}'
jane x 502 502 /home/jane /bin/bash
  만약 콤마를 쓰지 않는다면 아래처럼 더덕더덕 붙여서 나옵니다.
$ tail /etc/passwd | awk -F'[ :\t]' '/jane/{print $1$2$3$4$6$7}'
janex502502/home/jane/bin/bash

ORS: 출력용 레코드 구분 문자(output record separator)
  각 줄은 하나의 레코드로 취급하며 각 줄의 끝마다 레코드가 끝나는 것으로 취급합니다. 레코드 구분 문자(줄 구분 문자)는 줄 바꿈(new line)을 기본으로 사용합니다.

OFMT: 숫자 출력을 위한 서식(format for numeric output)
  이 변수를 통해 숫자의 서식을 제어할 수 있습니다. 기본 서식은 "%.6g"로 소수점 이하 6자리 수까지 표시합니다.

RS: 레코드 구분 문자(record separator)
  기본적으로 레코드 구분 문자는 줄 바꿈(new line)이다.

$0 변수
  파일 전체를 의미합니다.
$ awk '{print $0}' processes
USER       PID %CPU %MEM    VSZ RSS TTY STAT START TIME COMMAND
root         1  0.0  0.1  10348 720 ?   Ss   22:01 0:01 init [3]
root         2  0.0  0.0      0   0 ?   S<   22:01 0:00 [migration/0]
root         3  0.0  0.0      0   0 ?   SN   22:01 0:00 [ksoftirqd/0]
root         4  0.0  0.0      0   0 ?   S<   22:01 0:00 [watchdog/0]

2. 일반 변수
  숫자나 문자를 담는 변수입니다.
var=3 또는 var="test_string"

3. 배열 변수
  변수의 이름과 함께 숫자가 있는 대괄호의 조합으로 사용합니다.
variable_name[0]
variable_name[1]
2010/12/10 10:33 2010/12/10 10:33
Posted
Filed under 쉘 스크립트
참조 원문 : How To Search Using The Awk Utility
관련 글 : awk 기초, awk에서 변수 사용, 6가지 awk 트릭

  사실 검색만 놓고 따져보면 awk는 grep과 비교해 그리 큰 메리트가 없습니다만 awk의 본래 목적은 검색이 아니라 검색한 내용의 일부를 추출하는 것이기 때문에 awk를 사용하려면 검색 방법을 알아야 할 필요가 있습니다. 아래는 awk의 기본 문법입니다.
awk <search pattern> {<program actions>}
  awk로 검색을 할 때는 아래처럼 두 슬래시(/) 사이에 검색할 문자열을 넣습니다. 참고로 문자열에서 대소문자를 구분합니다.
/Debian/
  아래의 두 명령어는 같은 결과를 출력하는데 그 이유는 검색의 기본 기능은 화면에 대한 출력이기 때문입니다.
awk '/Debian/'
awk '/Debian/' {print}
  만약 "debian"과 "Debian"을 모두 검색하고 싶다면 아래처럼 정규식을 사용할 수 있습니다.
/[Dd]ebian/
  줄의 시작 부분을 검색하려면 "^" 문자를, 끝 부분을 검색하려면 "$" 문자를 사용합니다.
/^Debian/
/Debian$/
  아래는 d부터 m까지 소문자를 검색하는 경우입니다.
/[d-m]/
  다음 숫자를 검색하는 경우입니다.
/[0-9]/
  두 문자열 중 하나라도 일치하는 것이 있는 줄을 검색할 때는 파이파(|) 문자를 두 문자열 사이에 넣습니다. 그리고 이렇게 파이프(|)처럼 쉘이 해석하는 문자가 포함된 경우에는 쉘이 문자열을 맘대로 해석하지 않고 awk에게 온전히 넘겨주게 하기 위해 싱글 쿼트(')를 사용합니다. 사실 아래의 문자열에는 달러($), 백 쿼트(`), 이스케이프(\ 로 시작) 문자가 없기 때문에 더블 쿼트(")를 써도 같은 결과를 얻을 수 있지만 습관을 위해 awk에서는 싱글 쿼트를 쓰는 것이 좋다고 할 수 있겠습니다. 왜 싱글 쿼트(또는 아래의 경우 더블 쿼트도 포함)를 써야 하는지에 대한 자세한 정보는 이 포스트를 참고하시기 바랍니다.
awk '/Iceweasel|Epiphany/' access_log
  파일의 첫 번째 필드를 검색하려면 "$1"로 첫 번째 필드를 검색할 것임을 지정하고 "~" 문자로 해당 필드에서 문자열을 검색할 것임을 알립니다.
awk '$1 ~ /^192.168.5.103$/' access_log
  반대로 위의 상황에서 특정 문자열을 검색 결과에서 제외하려면 아래처럼 느낌표(!) 문자를 사용합니다.
awk '$1 !~ /^192.168.5.103$/' access_log
  아래는 'Debian'이라는 문자열이 있는 줄을 검색한 후 각 줄의 1번째와 20번째 필드를 출력하는 방법입니다.
awk '/Debian/' access_log | awk '{print $1,$20}'
  아래는 연속된 여러 줄을 출력하는 방법입니다.
awk 'NR == 10,NR == 15' access_log
  그리고 아래는 사용할 수 있는 연산자입니다.
<           미만
<=          이하
==          일치
!=          불일치
>=          이상
>           초과
  또한 AND 연산을 위한 &&와 OR 연산을 위한 ||도 사용이 가능합니다. 아래는 이를 이용하여 10번째 이상의 줄에서 첫 번째 필드가 두 IP 중 하나인 줄을 찾는 내용입니다.
awk '((NR >= 10) && ($1 == “192.168.5.103″)) || ($1 ==”192.168.5.104″)' access_log
  문자열 안에 넣을 수 있는 이스케이프 문자들은 아래와 같습니다.
\n     줄 바꿈 (라인 피드)
\t     수평 탭
\b     백스페이스
\r     캐리지 리턴
\f     폼 피드
2010/12/09 16:28 2010/12/09 16:28