10/120

김건호·2022년 2월 18일
0
post-custom-banner

awk

awk는 명령어를 작성한 A.V.Aho, P.J. Weinberger, B. Kernigham 의 머리글자를 따온 것
데이터 프로세싱, 리포트 작성, 간단한 데이터베이스 구축 등을 할 수 있음

특징

  1. 일정하지 않은 간격에 대한 구분을 해줌
  2. $0는 전체 필드를 나타냄
  3. cut과 다르게 순서를 바꿀 수 있음

구조 및 패턴

구조

awk [OPTION...] [pattern] [ARGUMENT...] 

패턴

[root@localhost ~]# cat data
hong 28 011-222-2222 seoul
park 34 017-333-3333 kyunggi
im 23 019-444-4444 chungnam
son 49 016-555-5555 us
gil 19 018-666-6666 korea
jang 21 011-7777-7777 japan
lee 16 016-8888-8888 china
sa 45 017-9999-9999 canada
hwang 32 015-555-5555 kwangju
  • BEGIN : 특정 명령을 실행하기 전에 먼저 실행
  • END : 특정 명령을 실행한 후 제시되는 문장을 실행
[root@localhost ~]# cat awkfilter
BEGIN {
 sum = 0;
 line = 0;
}
{
 sum += $2;
 line ++;
}
END {
average = sum / line;
print "나이의 평균 : "average"세";
}
  • /정규표현식/ : 정규표현식의 패턴을 포함하는 라인에서 문장을 실행
[root@localhost ~]# awk '{print $2}' data
28
34
23
49
19
21
16
45
32

[root@localhost ~]# for i in `awk '{print $2}' data`
> do
> sum=sum+$i
> done
[root@localhost ~]# sum=0
[root@localhost ~]# for i in `awk '{print $2}' data`; do sum=$sum+$i; done
[root@localhost ~]# echo $sum | bc
267

[root@localhost ~]# awk '$2 >25{print $2}' data
28
34
49
45
32

[root@localhost ~]# awk '$2 >25{print $1,$3}' data
hong 011-222-2222
park 017-333-3333
son 016-555-5555
sa 017-9999-9999
hwang 015-555-5555

[root@localhost ~]# awk '$2 >=25{print $1,$3}' data
hong 011-222-2222
park 017-333-3333
son 016-555-5555
sa 017-9999-9999
hwang 015-555-5555

[root@localhost ~]# awk '$2 >=25{print $1,$2}' data
hong 28
park 34
son 49
sa 45
hwang 32
  • 패턴1 && 패턴2 : 패턴1과 패턴2를 동시에 만족시킬 때 문장을 실행

  • 패턴1 || 패턴2 : 패턴1이나 패턴2 중 하나만 만족시켜도 문장을 실행

  • ! 패턴 패턴과 일치하지 않을 경우 문장을 실행

예제

  1. /etc/passwd 1000 uid 이상의 사용자는 일반유저입니다. 일반유저 정보만 출력해주세요. (단 계정명과, uid, 사용자 홈디렉토리 형태로 출력 해주세요.)
[root@localhost ~]# awk -F : '$3 >= 1000{print $1,$3,$6}'   /etc/passwd
nobody 65534 /
user 1000 /home/user
  1. 디스크 영역은 /dev로 시작됩니다. 40프로가 넘는 사용률을 가진 디스크를 출력해주세요
[root@localhost ~]# df -hTP |  sed 's/%//g' | awk '$1 ~ /^\/dev/ && $6 >= 40 {print$1, $6"%", $7}'
  • 우리 눈에는 n%가 숫자임을 알 수 있지만, 시스템은 알 수 없기때문에 sed로 %를 제거해준다
  • \를 사용하면 특수문자를 일반문자로 치환할 수 있음
  1. lastb는 접속 시간이 담겨있는 파일입니다. 그 중 접속 실패를 뜻하는 접속 시간이 0인 데이터만 모아져있습니다. localhost에서의 실패는 비밀번호 오류로 실패한 것이고, 그 이외에 아이피는 해킹일수도 있고, 아닐수도 있습니다. 예방차원에서 10번이상 실패한 주소를 찾아내주세요.
# lastb.txt
user     ssh:notty    192.168.110.200  Mon Oct  5 17:25 - 17:25  (00:00)    
user     ssh:notty    192.168.110.200  Mon Oct  5 17:13 - 17:13  (00:00)    
user     ssh:notty    192.168.110.200  Mon Oct  5 17:13 - 17:13  (00:00)    
user     ssh:notty    192.168.110.200  Mon Oct  5 17:13 - 17:13  (00:00)    
user     ssh:notty    192.168.110.200  Mon Oct  5 17:09 - 17:09  (00:00)    
user     ssh:notty    192.168.110.136  Mon Oct  5 17:08 - 17:08  (00:00)    
user     ssh:notty    192.168.110.136  Mon Oct  5 17:07 - 17:07  (00:00)    
userhat  ssh:notty    192.168.110.136  Mon Oct  5 16:27 - 16:27  (00:00)    
userhat  ssh:notty    192.168.110.136  Mon Oct  5 16:27 - 16:27  (00:00)    
userhat  ssh:notty    192.168.110.100  Mon Oct  5 16:27 - 16:27  (00:00)    
userhat  ssh:notty    192.168.110.100  Mon Oct  5 16:26 - 16:26  (00:00)    
userhat  ssh:notty    192.168.110.100  Mon Oct  5 16:26 - 16:26  (00:00)    
user     ssh:notty    192.168.110.110  Mon Oct  5 17:13 - 17:13  (00:00)    
user     ssh:notty    192.168.110.110  Mon Oct  5 17:09 - 17:09  (00:00)    
user     ssh:notty    192.168.110.110  Mon Oct  5 17:08 - 17:08  (00:00)    
user     ssh:notty    192.168.110.110  Mon Oct  5 17:07 - 17:07  (00:00)     
userman  ssh:notty    192.168.110.110  Mon Oct  5 16:26 - 16:26  (00:00)    
userman  ssh:notty    192.168.110.110  Mon Oct  5 16:25 - 16:25  (00:00)    
userman  ssh:notty    192.168.110.110  Mon Oct  5 16:25 - 16:25  (00:00)    
test     ssh:notty    localhost        Mon Oct  5 16:23 - 16:23  (00:00)    
test     ssh:notty    localhost        Mon Oct  5 16:23 - 16:23  (00:00)
userman  ssh:notty    192.168.110.136  Mon Oct  5 16:25 - 16:25  (00:00)    
userman  ssh:notty    192.168.110.136  Mon Oct  5 16:25 - 16:25  (00:00)    
userman  ssh:notty    192.168.110.136  Mon Oct  5 16:25 - 16:25  (00:00)    
userman  ssh:notty    192.168.110.136  Mon Oct  5 16:25 - 16:25  (00:00)    
userman  ssh:notty    192.168.110.136  Mon Oct  5 16:24 - 16:24  (00:00)    
test     ssh:notty    localhost        Mon Oct  5 16:23 - 16:23  (00:00)    
test     ssh:notty    localhost        Mon Oct  5 16:23 - 16:23  (00:00)    
test     ssh:notty    localhost        Mon Oct  5 16:23 - 16:23  (00:00)
userhat  ssh:notty    192.168.110.136  Mon Oct  5 16:26 - 16:26  (00:00)    
userhat  ssh:notty    192.168.110.136  Mon Oct  5 16:26 - 16:26  (00:00)    
test     ssh:notty    localhost        Mon Oct  5 16:23 - 16:23  (00:00)    
root     :0           :0               Mon Oct  5 11:02 - 11:02  (00:00)    

btmp begins Mon Oct  5 11:02:02 2020
[root@localhost ~]# awk  '$3 ~ /^[0-9]/{print $3}' lastb.txt | sort | uniq -c
3 192.168.110.100
7 192.168.110.110
11 192.168.110.136
5 192.168.110.200
[root@localhost ~]#  awk  '$3 ~ /^[0-9]/{print $3}' lastb.txt | sort | uniq -c | awk '$1 >= 10{print "10회이상 접속 ip =" $2}'
10회이상 접속 ip =192.168.110.136

uniq 앞에 반드시 sort가 존재해야 함

shell script

쉘에서 사용할 수 있는 명령어들의 조합을 모아서 만든 배치파일

스크립트란❓ 이너프리터에 의해 해석/실행되는 프로그램

// 쉘 스크립트 찾는 법
[root@localhost bin]# cd /bin; file * | grep "shell script"
Xorg:                               POSIX shell script, ASCII text executable
alias:                              POSIX shell script, ASCII text executable
alsaunmute:                         POSIX shell script, ASCII text executable
amuFormat.sh:                       POSIX shell script, ASCII text executable
anaconda-disable-nm-ibft-plugin:    POSIX shell script, ASCII text executable
bashbug-64:                         POSIX shell script, ASCII text executable, with very long lines
batch:                              POSIX shell script, ASCII text executable
bg:                                 POSIX shell script, ASCII text executable
bond2team:                          Bourne-Again shell script, ASCII text executable
...

첫 줄은 항상 #!/bin/스크립트이름 으로 되어 있음

실행 방법

  • 실행권한이 없을 때 :
[root@localhost ~]# bash test.sh
  • 실행권한이 있을 때 :
[root@localhost ~]# ./test.sh

문법

기본 출력

echo 명령어를 사용해 출력

#!/bin/sh
echo “This is a shell script file”

변수

변수를 쓸 때는 대문자로 하는 것이 좋음

# cat > number 
#!/bin/bash 
A=8 
B=5 
 
if [ $A -eq $B ] 
then 
 echo "$A is equal to $B" 
elif [ $A -gt $B ] 
then 
 echo "$A is greater than $B" 
elif [ $A -lt $B ] 
then 
 echo "$A is less than $B" 
fi

변수명 다음에 오는 '=' 좌우로는 공백이 있어서는 안됨

read

셸 스크립트에서 데이터를 입력 받는 명령어

#!/bin/bash

echo "A?"
read A
echo "B?"
read B

if [ $A == $B ]
then
    echo "$A is equal to $B"
fi

argument

쉘 스크립트에서는 인자로 데이터를 넘길 수 있음
인자가 전달되면 스크립트 내부에서는 $1, $2처럼, $n 형태로 인자를 읽을 수 있음(첫 번째인자는 0번)
n은 인자가 입력되는 순서를 의미
$#는 전달된 인자의 개수입니다.

# cat > argumentsh
#!/bin/sh
echo "argument1 : $1"
echo "argument2 : $2"
echo "argument3 : $3"
echo "Total argument number : $#"
echo "This file name : $0"
# sh argumentsh cpu ram hdd
argument1 : cpu
argument2 : ram
argument3 : hdd
Total argument number : 3
This file name : argumentsh
  • [$A –gt $B] : A값이 B값보다 크다.
  • [$A –lt $B] : A값이 B값보다 작다.
  • [$A –ge $B] : A값이 B값보다 크거나 같다.
  • [$A –le $B] : A값이 B값보다 작거나 같다.
  • [$A –eq $B] : A값과 B값이 같다.
  • [$A –ne $B] : A값과 B값이 다르다.

if

참이면(0을 반환하면) then 다음의 명령을 수행
거짓이면(0이 아닌 값을 반환하면) else 다음의 명령을 수행
elif는 if의 조건식이 거짓이 될 경우 다시 새로운 조건식을 검사

if 조건식 
then 
명령들 
[ elif 조건식 
then 
명령들 ] 
[ else 명령들 ] 
fi
#!/bin/bash 
echo “Type the filename: “₩c 
read filename 

if [ -e $filename ] 
then 
	echo $filename exists. 
else 
	echo $filename doesn\’t exist. 
fi 

파일의 존재유무를 확인할 때는 절대경로로 써야함

Loop

for

for aaa in you are so beautiful
do
echo $aaa
done

while

조건이 참일동안 반복
반복문을 배우며 쉘은 오토메이션이 가능하다는 것을 알 수 있음

// 사용자가 로그아웃하면 알리는 프로그램
[root@localhost ~]# cat > test1_logout_check.sh
#!/bin/bash
while who | grep ^test1 1> /dev/null
do
        sleep 5
done

프로그램을 백그라운드에서 실행

[root@localhost ~]# ./test1_logout_check.sh &
[1] 17296
[root@localhost ~]# jobs
[1]+  Running                 ./test1_logout_check.sh &

로그인 되어있던 유저가 로그아웃하면

echo "test1 유저가 지금 막 떠났습니다."

백그라운드에서 실행중인 프로그램 root에서 종료하기
1.kill 명령어

[root@localhost ~]# ps auxf | grep test1
root        8101  0.0  0.1  11160  3096 pts/1    S    02:25   0:00              \_ /bin/bash ./test1_login_check.sh
root        8129  0.0  0.0  10572  1120 pts/1    S+   02:26   0:00              \_ grep --color=auto test1
[root@localhost ~]# jobs
[1]+  Running                 ./test1_login_check.sh &
[root@localhost ~]# kill -9 8101
[root@localhost ~]# jobs
[1]+  죽었음               ./test1_login_check.sh
[root@localhost ~]# jobs
[root@localhost ~]# jobs
[root@localhost ~]# jobs
[root@localhost ~]# ./test1_login_check.sh &
[1] 8156
[root@localhost ~]# jobs
[1]+  Running                 ./test1_login_check.sh &
[root@localhost ~]# kill -9 %1
[root@localhost ~]# jobs
[1]+  죽었음               ./test1_login_check.sh
[root@localhost ~]#

주의할 점: kill 메모리에 올라간 프로세스를 특정 명령을 통해서 제어하고자 할 때 사용하는 명령어 (시그널) 좋은 방법이 아님. 실제로는 이렇게 하면 안됨. 프로그램의 현재상태를 모르기 때문에 메모리 영역 데이터와 디스크 영역 데이터 동기화 필요한데 강제로 죽여버려서 동기화되지 않은 데이터는 다 사라짐. 요즘은 파일시스템이 좋아져서 kill을 사용하는 경우가 많음. kill은 함부로 쓰면 안됨. 쓰기위해선 sync 명령어로 동기화 하기
2.시그널 보내기
fg %jobs_id 포그라운드도 종료를 할 수있음(정상)
CTRL + Z 대기모드 (누를때 주의할것)
CTRL + C 인터럽트로 정상종료
백그라운드로 돌아가기
bg=백그라운드 bg%1

until

조건이 참이 될때 까지 반복

[root@localhost ~]# cat test1_login_check.sh
#!/bin/bash
until who | grep ^test1
do
        sleep 5
done

예제

  1. ls -l /proc/PID/exe를 하면 어떤 프로그램을 실행시키는지 가르킵니다. 프로세스가 실제 어떤 프로그램에 연결되서 동작하는지 간추려서 보고 싶습니다.
[root@localhost ~]# for i in `ls /proc | grep ^[0-9]`
> do
> ls -l /proc/$i/exe 2>/dev/null
> done
  1. 링크카운터가 2인 파일 스캐너
#!/bin/bash
for i in `find . -type f -links 2 -print0 2> /dev/null | xargs -0 stat -c '%i %n' | cut -d' ' -f1 - | sort -n | uniq`
do
echo "$i num"
find / -inum $i 2> /dev/null
echo "========"
done
  1. 디렉토리 별 하드링크 파일 스캐너
#!/bin/bash

echo -n "DIR = "
read DIR

if [[ -z `stat -c '%F' $DIR/* 2>/dev/null | grep file$ 2>/dev/null` ]]
then
	echo "Hard link file not found."
	exit
fi

for i in `stat -c '%h %i %n %F' $DIR/* 2>/dev/null | grep file$ 2>/dev/null | awk '$1 > 1 {print $2}' | uniq`
do
	echo "$i i-nome"
	find / -inum $i 2>/dev/null
	echo "=============="
done
profile
Ken, 🔽🔽 거노밥 유튜브(house icon) 🔽🔽
post-custom-banner

0개의 댓글