Execute
이것은 sed 가지는 재미있는 기능 중 하나인데요.
pattern space 에 있는 내용을 명령문으로 해서 sh -c
형태로 실행을 시킬 수가 있습니다.
그리고 실행 결과가 다시 pattern space 로 저장됩니다.
그러므로 원하는 대로 또 결과를 수정해서 사용할 수 있겠죠?
다음은 명령을 실행했을 때 프로세스 상태입니다.
$ echo "2:3" | sed -E 's#([0-9]+):([0-9]+)#AA=$((\1+\2)); sleep $AA; echo $AA#e'
5
프로세스가 새로 생성되어 실행되므로 반복해서 여러번 실행할 경우 속도가 느려질 수 있습니다.
e
명령이 실행되는 형태를 2가지로 분류해 볼수 있습니다.
1. s/../../e 를 이용하는 방법, 단독으로 e 명령을 실행하는 방법
이 방법들은 현재 pattern space 에 있는 내용을 명령문으로 하여 sh -c
형태로 실행하고
stdout 값이 다시 pattern space 로 저장됩니다.
단독으로 e
명령을 실행할땐 이후에 다른 문자가 오지 못하므로
-e
옵션을 사용해 분리해야 합니다.
# 'echo hello' 가 pattern space 로 들어가고 'e' 명령에 의해 실행된다.
# 실행 결과 stdout 값이 다시 pattern space 로 저장된다.
$ echo "echo hello" | sed -e 'e' -e 's/.*/& execute/'
hello execute
2. pattern space 와 관계없이 e command
형식으로 직접 실행하는 방법
이 실행 방식은 i
명령과 동일합니다.
실행 결과가 patten space 에 영향을 주지 않고, -n
옵션에 상관없이 결과가 프린트됩니다.
명령문으로 사용되는 스트링은 어떤 값도 올수 있기 때문에 -e
옵션을 사용해 분리해야 합니다.
$ echo "hello" |
sed -n -e 'e echo ------------' -e 's/.*/& execute/p' -e 'e echo ============'
------------
hello execute
============
예제 1
다음 예제는 숫자가 포함된 데이터 파일을 읽어들여 max 값을 구한 후 출력합니다.
특별히 의미 있는 예제는 아니지만 여러 가지로 활용하는 방법을 보여줍니다.
sed 에서 사용되는
&
,\
문자를 shell 에서 사용하려면 escape 해야 합니다.
# 데이터 파일
$ cat data
43
2
85
12
5
999
7
26
------------------------
$ sed -En '
1{h;b} # 처음 숫자일 경우 hold 하고 END 로 분기합니다.
G # 현재 pattern space 에 있는 숫자에 hold space 에 있는 숫자를 append 합니다.
s/\n/ / # newline 을 space 로 변경하여 shell 에서 사용될 수 있게 합니다.
s#.*#set &; if [ $1 -gt $2 ]; then echo $1; else echo $2; fi #e
h # 연산 결과를 hold 합니다.
$p # 마지막 라인일 경우 값을 표시합니다.
' data
999
------------------------
$ sed -En '
1{h;b}
G
s/\n/ / # f() 쉘 함수를 만들어 실행
s#.*#f() { if [ $1 -gt $2 ]; then echo $1; else echo $2; fi ;}; f & #e
h
$p
' data
999
------------------------
# comp.sh script 를 만들어 실행
$ cat comp.sh
#!/bin/sh
if [ "$1" -gt "$2" ]; then
echo "$1"
else
echo "$2"
fi
..........................
$ sed -En '
1{h;b}
G
s/\n/ /
s#.*#./comp.sh &#e # comp.sh 스크립트를 실행
h
$p
' data
999
예제 2
이번에는 각 라인의 합계를 구합니다.
$ shuf -i 1-20 | paste - - - - -
16 7 12 20 17
2 4 9 3 6
19 1 11 8 13
15 14 10 18 5
$ shuf -i 1-20 | paste - - - - - |
sed -E '
p
# `s` 명령에 의해 다음과 같은 스트링이 `sh -c` 에 의해 실행됩니다.
# f() { for n; do r=$((r+n)); done; echo "sum : $r" ;}; f 7 12 1 10 16
s/^/f() { for n; do r=$((r+n)); done; echo "sum : $r" ;}; f /e
'
7 12 1 10 16
sum : 46
11 2 18 17 8
sum : 56
13 5 4 3 15
sum : 40
19 6 9 20 14
sum : 68
예제 3
다음은 데이터 파일에 있는 도메인의 ip 주소를 구하여 추가합니다.
$ cat host
001 naver.com KR
002 daum.net KR
003 google.com US
$ sed -En '
h
s#.* (.*) .*#dig +short \1 | head -n1#e
G
s#(.*)\n(.*) (.*) (.*)#\2 \3 : \1 \4 #
p
' host
001 naver.com : 202.179.177.22 KR
002 daum.net : 61.111.62.173 KR
003 google.com : 216.58.197.142 US