lecture/script 언어

기초 shell script 문법 2 (awk ,sed 설명 및 실습활용)

infra 2021. 10. 29. 17:50

1.awk 설명

 

AWK(오크)는  유닉스에서  처음  개발된  일반  스크립트  언어이다.
AWK의  기본  기능은  텍스트  형태로  되어있는  입력  데이터를  행과  단어  별로  처리해  출력하는  것이다.

 

명령의  수행  결과나  파일의  데이터  내용을  한  줄씩  읽어  들여,
한  줄의  내용을  단어  단위로  끊어서  읽어  들이고  이를  조작  및  연산에  활용할  수  있다. 

 

특징 script 형식
해설
실행 awk ‘패턴  {동작} 패턴  {동작} ... 패턴  {동작}’  파일명 

command  |  awk ‘패턴  {동작} 패턴  {동작} ... 패턴  {동작}’ 

awk –f  awk파일명    파일명
N/A
BEGIN { 동작  } 
END { 동작  }
/패턴/
{ 동작  }
print  
-BEGIN은  입력을  읽기  전에  주어진  '동작'을  먼저  실행한다.

-END도 입력을  모두  훑고  마지막에  주어진  '동작'을  실행한다. 

-'패턴'에  일치하는  줄을  출력한다.
-매  줄을  읽을  때마다  '동작'을  실행한다. 
-텍스트를  출력한다.
주요 키워드
Built-in Variables (변수)
FILENAME
NR 
NF
FS
OFS
– 입력된  파일의  이름 
– 현재  행의  번호
– 현재  행의  단어의  개수 
– 입력  단어  분리자 (-F 옵션)
 – 출력  단어  분리자

 

문제 상황은 다음과 같다.

 

1. #vi information.txt   //텍스트파일은 다음 3줄까지 작성

 

1,Lee,02-123-4567,010-1234-5678,Seoul
2,S,031-234-5678,010-2345-6789,Inchon
3,H,051-345-6789,010-3456-7890,Pusan

 

실습문제1

 

출력값은 다음과 같이 나와야 한다.

address book
<(1)Lee>
Phone Number:02-123-4567
Mobile Number:010-1234-5678
City:Seoul
<(2)S>
Phone Number:031-234-5678
Mobile Number:010-2345-6789
City:Inchon
<(3)H>
Phone Number:051-345-6789
Mobile Number:010-3456-7890
City:Pusan
Total 3address.

 

 

실습문제2

information 텍스트파일을 통해 응용해보자 .

2번째 필드(name=$2)와 4번째 필드(mobile=$4)를 출력하게 하라

 

해당 출력값은 다음과 같이 나와야 한다.

 

Lee     010-1234-5678
S       010-2345-6789
H       010-3456-7890

더보기

상황

information 이라는 텍스트 파일을 만들어, 해당필드마다 구분짓는 라인에 ,로 구분지어 작성 후 

아래의 스크립트를 넣어 실행시켜준다.

 

 

<실습문제1>

 

 

1. #vi information.txt   //텍스트파일은 다음 3줄까지 작성

 

1,Lee,02-123-4567,010-1234-5678,Seoul
2,S,031-234-5678,010-2345-6789,Inchon
3,H,051-345-6789,010-3456-7890,Pusan

 

2.#vi awk_test1.sh   //sh 파일은 다음 10줄까지 작성

 

1 #!/bin/sh
2 /bin/awk \
3   'BEGIN {FS = ","; print "address book"}\
4  {idx=$1}{name=$2}{phone=$3}{mobile=$4}{city=$5}\
5  {n += 1}\
6  {print"<("idx")"  name ">"}\
7  {print"Phone Number:" phone}
8  {print"Mobile Number:" mobile}
9  {print"City:" city}\
10  END {print"Total "n"address."}information.txt

 

설명 :

3번째 줄 부터 10번째 줄까지 BEGIN 첫시작부터

3번째 줄은 `BEGIN {}\ 구문이 있는 부분을 우선 동작부터 실행되게 한다.

즉, 입력(4~9번째줄) 읽기 전에 동작 먼저 실행

 

 

3. //chmod +x 해당 sh 파일

4.//실행

 

<결과값>

[root@centos7 awk_test]# vi information.txt
[root@centos7 awk_test]# ./awk_test1.sh
address book
<(1)Lee>
Phone Number:02-123-4567
Mobile Number:010-1234-5678
City:Seoul
<(2)S>
Phone Number:031-234-5678
Mobile Number:010-2345-6789
City:Inchon
<(3)H>
Phone Number:051-345-6789
Mobile Number:010-3456-7890
City:Pusan
Total 3address.

 

 

실습문제2

 

information 텍스트파일을 통해 응용해보자 .

2번째 필드(name=$2)와 4번째 필드(mobile=$4)를 출력하게 하라

 

 

[root@centos7 awk_test]# awk -F, '{print $2 "\t" $4}' information.txt
Lee     010-1234-5678
S       010-2345-6789
H       010-3456-7890

 

해설:

F는 분리시키는 옵션으로서

아까 information.txt파일보면 1,Lee,02-123-4567,010-1234-5678,Seoul

이런식으로 각각 쉼표로 분리해놓은 상태이다.

 

– 입력  단어  분리자 (-F 옵션)

https://infraleesh.tistory.com/40?category=982663 

/etc/passwd의 디렉터리구조는 위의 참조하길 바란다.

$1= 첫번째 필드를 의미하고, 첫번째 옵션에 있는 것을 의미한다.

첫번째 필드는 유저명이고, root, bin, daemon ... 이 순서로 apache까지 있는 부분을 의미한다.

$6= 여섯번째 필드이며, 위의 URL에서도 home 디렉터리를 나타내는 부분이다.그래서 root계정은 /root,일반 사용자계 정은 /home/유저명1, home/유저명2 이런식으로 표현되어있다.

 

 

더보기

script안의 awk를 사용하여 사용하여 수행 방법1

 

1.[root@centos7 awk_test]# vi users_home.sh

#!/bin/sh
/bin/awk \
'BEGIN { FS = ":" } \
        { print $1 " home at " $6 }' \
/etc/passwd
2.[root@centos7 awk_test]# chmod +744 users_home.sh

3.[root@centos7 awk_test]# ./users_home.sh

 

 

script사용하지 않고 awk 명령어로 수행방법2

awk -F: '{print $1 " home at "$6}' /etc/passwd

 

2개 모두 같은 동일한 값을 가져올 수 있다.

 

수행방법1처럼 shell script를 짜지 않고도 동일하게 명령어 한줄로도 뽑아낼 수 있다.

 

cat /etc/passwd로 확인해보면 각각 : 콜론으로 분리해놓은상태다

 

cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
...

 

그래서 -F옵션 뒤 :으로 구분짓고,

1번째,6번째 필드 사이에 " home at "을 추가해준 후 명령어를 수행한 것을 알 수 있다.

 

[root@centos7 awk_test]# awk -F: '{print $1 " home at "$6}' /etc/passwd
root home at /root
bin home at /bin
daemon home at /sbin
adm home at /var/adm
lp home at /var/spool/lpd
sync home at /sbin
shutdown home at /sbin
halt home at /sbin
mail home at /var/spool/mail
operator home at /root
games home at /usr/games
ftp home at /var/ftp
nobody home at /
systemd-network home at /
dbus home at /
polkitd home at /
postfix home at /var/spool/postfix
sshd home at /var/empty/sshd
test1 home at /home/test1
test2 home at /home/test2
tss home at /dev/null
geoclue home at /var/lib/geoclue
chrony home at /var/lib/chrony
rtkit home at /proc
colord home at /var/lib/colord
pulse home at /var/run/pulse
gdm home at /var/lib/gdm
apache home at /usr/share/httpd

 

 

 

실습문제 3

 

3.information.txt 파일을 활용해서 count 문을 사용해서 총 몇개인지 파악하라.

 

[root@centos7 awk_test]# awk '{++cnt} END {print "Count = ", cnt}' information.txt
Count =  3

 

 

 

 


[2]sed 정의

 

sed(Stream EDitor) : unix에서 텍스트를 분해하거나 변환하기 위한 프로그램이다.

unix의 여러가지 OS에서 사용이 가능하다.

 

대상이 되는 파일의 내용을 원하는 형태로 변경 가능

 

사용법

 

특징 script 형식
해설
실행 예시

sed 's/regexp/replacement/g' 입력파일명 > 출력파일명


입력파일명을 읽어 전체에서 regexp 패턴을 찾아 replacement로 치환한 후 출력파일명으로 쓴다.

generateData | sed ‘s/x/y/g’

# echo xyz xyz | sed ‘s/x/y/g’
yyz yyz
-generateData 수행  후  데이터를  만든  다음  x를  y로  치환한다.

-
해설
구문
s/원본/치환할 문자/g'

s: 특정 문자열을 다른 문자열로 변환
g:범위 global

주요 키워드
Built-in Variables (변수)
옵션의 종류
1)s
2)i
3)a
4)d
5)c
6)p
1)s 특정 문자열을 다른 문자열로 변환
2)i : 문자열 삽입(insert)
3)a: 새로운 행을 추가 (add)
4)d:행을 삭제(delete)
5)c: 특정행을 다른 행으로 변환(change)
6)p : 출력(print)

다시 awk 명령어 실습동안 사용했던 information.txt 대신 약간 변형해서 해당 텍스트파일을 활용하자.

 

1,Lee,02-123-4567,010-1234-5678,Seoul
2,Squid,031-234-5678,010-2345-6789,Inchon
3,Game,051-345-6789,010-3456-7890,Pusan

 

실습1.

 

더보기


[root@centos7 sed_test]# sed 's/Squid/SQLD/g' information.txt         //해석:  Squid 문자열을 SQLD로 변환/
1,Lee,02-123-4567,010-1234-5678,Seoul
2,SQLD,031-234-5678,010-2345-6789,Inchon
3,Game,051-345-6789,010-3456-7890,Pusan


더보기

[root@centos7 sed_test]# sed 's/051/02/1' information.txt      

                                                       //해석 : 쉘에서 051이라는 문자가 첫(1)번째로 나왔을 때 02로 변경하라
1,Lee,02-123-4567,010-1234-5678,Seoul
2,Squid,031-234-5678,010-2345-6789,Inchon
3,Game,02-345-6789,010-3456-7890,Pusan

 


더보기


[root@centos7 sed_test]# sed 's/123/XXX/2' information.txt

                                                
1,Lee,02-123-4567,010-XXX4-5678,Seoul
2,Squid,031-234-5678,010-2345-6789,Inchon
3,Game,051-345-6789,010-3456-7890,Pusan

 

//해석 : 쉘에서 123이라는 문자가 두(2)번째로 나왔을 때 XXX로 변경

첫쨰 Lee 줄에서 123이 첫번째로 나온것은 무시하고, 두번째로 나온 123을 XXX로 변경하라는 의미

 

 


실습2

더보기

[root@centos7 sed_test]# cat information.txt
1,Lee,02-123-4567,010-1234-5678,Seoul
2,Squid,031-234-5678,010-2345-6789,Inchon
3,Game,051-345-6789,010-3456-7890,Pusan

 

1. 해당 텍스트파일의 2번째 줄을 삭제하라

 

[root@centos7 sed_test]# sed '2d' information.txt
1,Lee,02-123-4567,010-1234-5678,Seoul
3,Game,051-345-6789,010-3456-7890,Pusan

 

 

2.해당 텍스트파일의 5678이 나오는 줄을 삭제하라

[root@centos7 sed_test]# sed '/5678/d' information.txt
3,Game,051-345-6789,010-3456-7890,Pusan

 

 

3.해당 텍스트파일의 Game이 나오는 줄을 삭제하라

 
[root@centos7 sed_test]# sed '/Game/d' information.txt
1,Lee,02-123-4567,010-1234-5678,Seoul
2,Squid,031-234-5678,010-2345-6789,Inchon

 

4.

(1)2번째 줄에 2,New,00-000-0000,000-000-0000,Korea 를 삽입하라.

 

[root@centos7 sed_test]# sed '2i\2,New,00-000-0000,000-000-0000,Korea' information.txt
1,Lee,02-123-4567,010-1234-5678,Seoul
2,New,00-000-0000,000-000-0000,Korea
2,Squid,031-234-5678,010-2345-6789,Inchon
3,Game,051-345-6789,010-3456-7890,Pusan

(2)

[root@centos7 sed_test]# sed '4i\4,New,00-000-0000,000-000-0000,Korea' information.txt
1,Lee,02-123-4567,010-1234-5678,Seoul
2,Squid,031-234-5678,010-2345-6789,Inchon
3,Game,051-345-6789,010-3456-7890,Pusan

 

(3)

[root@centos7 sed_test]# sed '4a\4,New,00-000-0000,000-000-0000,Korea' information.txt
1,Lee,02-123-4567,010-1234-5678,Seoul
2,Squid,031-234-5678,010-2345-6789,Inchon
3,Game,051-345-6789,010-3456-7890,Pusan

 

(4)

[root@centos7 sed_test]# sed '3a\4,New,00-000-0000,000-000-0000,Korea' information.txt
1,Lee,02-123-4567,010-1234-5678,Seoul
2,Squid,031-234-5678,010-2345-6789,Inchon
3,Game,051-345-6789,010-3456-7890,Pusan
4,New,00-000-0000,000-000-0000,Korea
[root@centos7 sed_test]#

 

(2)i옵션은 중간에 삽입해야되고, 끝에 추가하는거는 아니여서 적용되지 않는다.

(3)그리고 4a로 추가하려했으나, 적용되지 않는다.

(4)기존의 마지막 3번째에서 add 옵션을 활용해야 마지막에 추가된것으로 보인다.

 

 

'lecture > script 언어' 카테고리의 다른 글

입력&출력[ 재지향(>,>>,2&1), 파이프(|)]  (0) 2021.11.25
환경변수 및 shell  (0) 2021.11.09
기초 shell script 문법 1  (0) 2021.10.29