String functions
sub ( regex, replacement [, target ] )
gsub ( regex, replacement [, target ] )
sub 와 gsub 함수를 함께 설명합니다.
regex 에는 상수 (/.../
) 와 quotes ("..."
) 모두 사용할 수 있습니다.
sub
함수는 첫 번째 매칭에 대해서만 치환을 하고 gsub
함수는
전체 매칭에 대해서 모두 치환을 합니다.
반환값은 치환이 일어난 개수인데 sub 함수의 경우는 한번만 치환을 하므로
1 또는 0 이 됩니다.
target 스트링이 주어지지 않으면 기본적으로 $0
이 사용됩니다.
######################## sub #########################
$ awk '
BEGIN {
str = "foo boo zoo"
num = sub(/o+/, "XX", str)
print str
print "number of substitutions made : " num
}'
fXX boo zoo
number of substitutions made : 1
...............................................
# target 스트링이 주어지지 않으면 `$0` 가 사용됩니다.
$ echo foo boo zoo | awk ' {
num = sub(/o+/, "XX")
print
print "number of substitutions made : " num
}'
fXX boo zoo
number of substitutions made : 1
######################## gsub #########################
$ awk '
BEGIN {
str = "foo boo zoo"
num = gsub(/o+/, "XX", str)
print str
print "number of substitutions made : " num
}'
fXX bXX rXX
number of substitutions made : 3
................................................
# target 스트링이 주어지지 않으면 `$0` 가 사용됩니다.
$ echo foo boo zoo | awk ' {
num = gsub(/o+/, "XX")
print
print "number of substitutions made : " num
}'
fXX bXX rXX
number of substitutions made : 3
&
는 매칭된 스트링을 나타내고 replacement 부분에서 사용될 수 있습니다.
######################## sub #########################
$ awk '
BEGIN {
str = "foo BAR ZOO"
num = sub(/[A-Z]+/, "@&@", str)
print str
}'
foo @BAR@ ZOO
######################## gsub #########################
$ awk '
BEGIN {
str = "foo BAR ZOO"
num = gsub(/[A-Z]+/, "@&@", str)
print str
}'
foo @BAR@ @ZOO@
regex 문자인 |
나 &
를 일반 문자로 사용하려면 escape 해야 합니다.
regex 상수(/.../
) 와 달리 quotes 에서는 기본적으로 escape sequence 가 처리되므로
\&
가 전달되기 위해서는 \
문자를 두번 사용해야 합니다.
######################## sub #########################
$ awk '
BEGIN {
str = "foo|boo|zoo"
num = sub(/\|/, "\\&", str)
print str
}'
foo&boo|zoo
######################## gsub #########################
$ awk '
BEGIN {
str = "foo|boo|zoo"
num = gsub(/\|/, "\\&", str)
print str
}'
foo&boo&zoo
gensub ( regex, replacement, how [, target ] )
gensub 는 sub, gsub 함수와 달리 치환된 스트링 결과가 target 스트링에 설정되지 않고
함수의 return 값으로 전달됩니다.
target 스트링이 주어지지 않았을 경우 입력값으로는 $0
이 사용되나
출력값은 $0
에 대입되지 않으므로 직접 $0
나 변수에 대입해서 사용해야 됩니다.
gensub 는 다음과 같이 gsub 함수에 비해 좀 더 확장된 기능을 가지고 있습니다.
how
인수를 통해서 매칭 번호를 지정할 수 있습니다. ( 1, 2, 3 ... 9, "g" )
$ awk '
BEGIN {
str = "foo BAR ZOO"
res = gensub(/[A-Z]+/, "@&@", 1, str) # how : 1
print res
}'
foo @BAR@ ZOO
$ awk '
BEGIN {
str = "foo BAR ZOO"
res = gensub(/[A-Z]+/, "@&@", 2, str) # how : 2
print res
}'
foo BAR @ZOO@
$ awk '
BEGIN {
str = "foo BAR ZOO"
res = gensub(/[A-Z]+/, "@&@", "g", str) # how : "g"
print res
}'
foo @BAR@ @ZOO@
.........................................................
# target 스트링이 주어지지 않으면 입력값으로는 $0 가 사용되지만
# 출력값은 $0 에 대입되지 않으므로 직접 대입해 사용해야 합니다.
$ echo foo BAR ZOO | awk '{
$0 = gensub(/[A-Z]+/, "@&@", "g")
print
}'
foo @BAR@ @ZOO@
( )
subexpression 을 이용한 back-reference 를 사용할 수 있습니다.
$ awk '
BEGIN {
str = "XXX YYY"
res = gensub(/([A-Z]+) ([A-Z]+)/, "\\2 \\1", "g", str)
print res
}'
YYY XXX
..........................................................
# 매칭이 되면 값에서 @...@ 가 분리되지만
$ awk 'BEGIN { str = "@foo@"; print gensub( /^@(.*)@$/, "\\1", "1", str ) }'
foo
# 매칭이 안되면 원본이 그대로 출력됩니다.
$ awk 'BEGIN { str = "bar"; print gensub( /^@(.*)@$/, "\\1", "1", str ) }'
bar
한가지 주의할 점은 /.../
매칭에 포함되지 않는 스트링은
함께 출력된다는 점입니다.
다음의 경우 스트링에서 숫자 부분만 추출하려고 한 것인데 실제 결과는
앞의 공백이 함께 출력됩니다.
$ echo " 123ABC" | awk '{ print "X" gensub( /([0-9]+)[A-Z]+/, "\\1","g") "X" }'
X 123X
# 다음과 같이 스트링 전체를 매칭해야 ( ) 부분만 추출됩니다.
$ echo " 123ABC" | awk '{ print "X" gensub( /\s*([0-9]+)[A-Z]+/, "\\1","g") "X" }'
X123X
match ( string, regex [, array ] )
첫 번째 매칭 되는 스트링의 포지션을 반환합니다.
매칭 되는 스트링이 없을 경우는 0
이 반환됩니다.
이 함수는 또한 RSTART
와 RLENGTH
변수를 설정합니다.
regex 에 ( )
를 사용하고 array 인수를 사용하면
실제 매칭 된 스트링 값이 array 변수에 설정됩니다.
매칭 될 경우 | 매칭이 안될 경우 | |
---|---|---|
RSTART | 해당 포지션 | 0 |
RLENGTH | 매칭 스트링 length | -1 |
인수에 사용된 regex 과 string 순서가 sub 함수와 다른데 ~
연산자를 생각하시면 됩니다.
$0 ~ /bar+/
$ echo fooXXXbarrr |
awk '{
where = match($0, /bar+/)
print where, RLENGTH
print RSTART, RLENGTH
}'
7 5
7 5
regex 에 ( )
를 사용하면 array 값을 사용할 수 있습니다.
array 에는 실제 매칭된 스트링과 start, length 값이 설정됩니다.
$ echo fooXXXbarrr |
awk '{
where = match($0, /(bar+)/, arr)
print arr[1], where, RLENGTH
print arr[1], RSTART, RLENGTH
print arr[1], arr[1, "start"], arr[1, "length"]
}'
barrr 7 5
barrr 7 5
barrr 7 5
$ echo fooXXXbarrr |
awk '{
match($0, /(fo+).+(bar*)/, arr)
print arr[1], arr[1, "start"], arr[1, "length"]
print arr[2], arr[2, "start"], arr[2, "length"]
}'
foo 1 3
barrr 7 5
사용 예제 )
# 파일명과 디렉토리명 구하기
$ echo 'aaa/bbb/README.md' | awk '{print substr($0,match($0,/[^/]+$/))}'
README.md
$ echo 'aaa/bbb/README.md' | awk '{print substr($0,1,match($0,/[^/]+$/)-2)}'
aaa/bbb
--------------------------------------------------
# regex 매칭 스트링을 같은 length 의 space 로 치환
$ cat file
VBoxManage natnetwork add --netname <name>
VBoxManage natnetwork remove --netname <name>
VBoxManage natnetwork modify --netname <name>
$ awk -v str="VBoxManage natnetwork" '
{ if (match($0, str)){ sub(str, sprintf("%*s", RLENGTH,"")); print }}' file
add --netname <name>
remove --netname <name>
modify --netname <name>
split ( string, fields [, fieldsep [, seps ] ] )
아래와 같은 str 이 있을 경우 /@[A-Z]+@/
를 field separator 로 잡고 split 하게 되면
(hello ) (, this is a ) ( end.)
가 fields 가 되고 (@AAA@) (@BBB@)
가 separators 가 됩니다.
필드 개수가 반환되고 전체 flds 와 seps 값을 합치면 str 이 됩니다.
$ awk -f - <<\EOF
BEGIN {
str = "hello @AAA@, this is a @BBB@ end."
num = split (str, fld, /@[A-Z]+@/, sep) # fld 와 sep 은 array 가 됩니다.
print "number of flds : " num
for ( i in fld )
printf "%s. fld: (%s) \t sep: (%s)\n", i, fld[i], sep[i]
}
EOF
number of flds : 3
1. fld: (hello ) sep: (@AAA@)
2. fld: (, this is a ) sep: (@BBB@)
3. fld: ( end.) sep: ()
patsplit ( string, fields [, fieldpat [, seps ] ] )
이 함수는 split 함수와 비슷하지만 다른 점은 FPAT 을 이용해 필드를 추출하는 것처럼 필드를 분리합니다.
따라서 /@[A-Z]+@/
가 field pattern 이 되어 매칭된 (@AAA@) (@BBB@)
가 필드가 되고
(hello ) (, this is a ) ( end.)
가 separators 가 됩니다.
한가지 참고할 것은 첫 번째 필드값 (@AAA@)
앞에 위치한 (hello )
는 sep index 가 0
이 됩니다.
필드 개수가 반환되고 전체 seps 와 flds 값을 합치면 str 이 됩니다.
$ awk -f - <<\EOF
BEGIN {
str = "hello @AAA@, this is a @BBB@ end."
num = patsplit(str, fld, /@[A-Z]+@/, sep) # fld 와 sep 은 array 가 됩니다.
print "number of flds : " num
printf "\t \tsep: (%s)\n", sep[0] # sep index 가 0
for ( i in fld )
printf "%s. fld: (%s) sep: (%s)\n", i, fld[i], sep[i]
}
EOF
number of flds : 2
sep: (hello )
1. fld: (@AAA@) sep: (, this is a )
2. fld: (@BBB@) sep: ( end.)
substr ( string, start [, length ] )
start 포지션과 length 를 이용하여 원하는 스트링을 추출할 수 있습니다.
C 언어에서와는 달리 첫 번째 문자의 포지션 값은 1 입니다.
$ awk 'BEGIN { str="abcdef"; print substr(str, 2, 3) }'
bcd
$ awk 'BEGIN { str="abcdef"; print substr(str, 2) }'
bcdef
$ echo "hello world" | awk '{ print substr($0, 1, 5) " 123 " substr($0, 7) }'
hello 123 world
sub, gsub 함수의 경우 함수 실행 결과가 다시 target 스트링에 대입되기 때문에 target 스트링에 substr 함수를 사용할 수 없습니다. 하지만 gensub 함수는 사용할 수 있습니다.
# gensub 함수 에서는 target 스트링에 substr 함수를 사용할 수 있습니다.
$ echo "hello world" | awk '{ print gensub( /l/, "X", "g", substr($0, 1, 5)) }'
heXXo
index ( in, find )
매칭 되는 스트링의 포지션을 구할 때 사용합니다.
매칭 되는 스트링이 없을 경우 0 이 반환됩니다.
$ awk 'BEGIN { print index("peanut", "pea") }'
1
$ awk 'BEGIN { print index("peanut", "nu") }'
4
............................................
$ sudo awk -b -v RS='^$' '{ print index($0, "\037\213\010") }' /boot/vmlinuz-4.13.0-39-generic
18357
length ( [ string ] )
length 함수는 scalar 변수와 array 변수에서 각각 다르게 적용됩니다.
scalar 변수에서는 string length 가 되고 array 변수에서는 array length 가 됩니다.
string 값이 주어지지 않으면 $0
값이 사용됩니다.
$ awk 'BEGIN { print length("peanut") }'
6
# string 값이 주어지지 않으면 `$0` 값이 사용됩니다.
$ echo "peanut" | awk '{ print length() }'
6
# 15 * 35 = 525 이므로 length 는 3 이 된다.
$ awk 'BEGIN { print length(15 * 35) }'
3
strtonum ( string )
숫자가 0 으로 시작하면 8 진수로, 0x ( 0X ) 로 시작하면 16 진수로 인식이 되는데요.
그런데 입력 스트림이나 -v
옵션에 의해 외부로부터 값이 전달되는 경우는
기본적으로 모두 스트링으로 취급되므로 10 진수와 달리 정상적으로 연산이 되지 않습니다.
이때 사용할 수 있는 함수입니다.
# 스크립트 내에서 직접 8, 16 진수를 사용할 때는 정상적으로 연산이 된다.
$ awk 'BEGIN { print 011; print 011 + 1 }'
9
10
$ awk 'BEGIN { print 0x11; print 0x11 + 1 }'
17
18
# 외부에서 값이 전달될 때는 스트링이 되므로 정상적으로 연산이 되지 않는다.
$ echo 011 | awk '{ print $1; print $1 + 1 }'
011
12
$ echo 0x11 | awk '{ print $1; print $1 + 1 }'
0x11
1
# 이때 strtonum 함수를 사용할 수 있습니다.
$ echo 011 0x11 | awk '{ print strtonum($1) + 1; print strtonum($2) + 1 }'
10
18
sprintf ( format, expression1, ... )
sprintf 함수는 포멧 출력값을 변수로 저장할 때 사용합니다.
$ awk 'BEGIN { pi = sprintf("pi = %.2f", 22/7); print pi }'
pi = 3.14
tolower ( string )
대문자를 소문자로 변환합니다.
$ awk 'BEGIN { print tolower("MiXeD cAsE 123") }'
mixed case 123
toupper ( string )
소문자를 대문자로 변환합니다.
$ awk 'BEGIN { print toupper("MiXeD cAsE 123") }'
MIXED CASE 123
asort ( source [, dest [, how ] ] )
해당 페이지 참조
asorti ( source [, dest [, how ] ] )
해당 페이지 참조