awk는 명령어를 작성한 A.V.Aho, P.J. Weinberger, B. Kernigham 의 머리글자를 따온 것
데이터 프로세싱, 리포트 작성, 간단한 데이터베이스 구축 등을 할 수 있음
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
[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 중 하나만 만족시켜도 문장을 실행
! 패턴 패턴과 일치하지 않을 경우 문장을 실행
[root@localhost ~]# awk -F : '$3 >= 1000{print $1,$3,$6}' /etc/passwd
nobody 65534 /
user 1000 /home/user
[root@localhost ~]# df -hTP | sed 's/%//g' | awk '$1 ~ /^\/dev/ && $6 >= 40 {print$1, $6"%", $7}'
# 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가 존재해야 함
쉘에서 사용할 수 있는 명령어들의 조합을 모아서 만든 배치파일
스크립트란❓ 이너프리터에 의해 해석/실행되는 프로그램
// 쉘 스크립트 찾는 법
[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
변수명 다음에 오는 '=' 좌우로는 공백이 있어서는 안됨
셸 스크립트에서 데이터를 입력 받는 명령어
#!/bin/bash
echo "A?"
read A
echo "B?"
read B
if [ $A == $B ]
then
echo "$A is equal to $B"
fi
쉘 스크립트에서는 인자로 데이터를 넘길 수 있음
인자가 전달되면 스크립트 내부에서는 $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
참이면(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
파일의 존재유무를 확인할 때는 절대경로로 써야함
for aaa in you are so beautiful
do
echo $aaa
done
조건이 참일동안 반복
반복문을 배우며 쉘은 오토메이션이 가능하다는 것을 알 수 있음
// 사용자가 로그아웃하면 알리는 프로그램
[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
조건이 참이 될때 까지 반복
[root@localhost ~]# cat test1_login_check.sh
#!/bin/bash
until who | grep ^test1
do
sleep 5
done
[root@localhost ~]# for i in `ls /proc | grep ^[0-9]`
> do
> ls -l /proc/$i/exe 2>/dev/null
> done
#!/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
#!/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