bash script2023. 7. 25. 16:17

 

반달가면 이글루에서 백업 - http://bahndal.egloos.com/592518

예전에 sed에서 역슬래시-괄호를 이용한 영역 구분 및 문자열 재구성 작업 방법을 정리해 두었는데, 같은 종류의 작업을 awk에서도 할 수 있다. 문자열의 영역을 설정해서 자리를 바꾸거나 내용을 대체하거나 하는 등의 작업이다.

 

우선 awk에서 제공하는 gensub 함수를 보자. 통상적인 문자열 대체는 sub, gsub 함수를 사용할 수 있지만 영역을 설정하는 것은 gensub 함수를 이용해야 한다. (sub, gsub 함수에 대한 내용은 이전 게시물을 참고하자. 여기로)

 

gensub 함수의 형식은 아래와 같다.

gensub(/문자열 또는 정규표현식/, "대체할 문자열", 실행옵션, 대상)

"대상" 문자열에서 "/문자열 또는 정규표현식/"을 찾아서 "대체할 문자열"로 바꾼다. 실행 옵션은 조건을 만족하는 모든 경우에 변경을 하고 싶으면 "g", 첫번째로 일치하는 부분에 대해서만 변경하려면 "" 이렇게 해 주면 된다. 간단한 예시를 보자.

# 기본: 행 전체($0)에 대해서 첫번째로 출현하는 문자열 "abc"를 "123"으로 대체하여 변수 result에 저장하고 출력
echo "ababcdef" | awk '{ result=gensub(/abc/, "123", "", $0); print result }'
ab123defabc

# 조건에 맞는 모든 경우에 대해 대체
echo "ababcdef" | awk '{ result=gensub(/abc/, "123", "g", $0); print result }'
ab123def123

자, 이제 영역구분을 통한 재구성을 생각해 보자. sed와 유사하게 소괄호를 사용한다. 아래의 예시를 보자. b 또는 c 또는 d가 나올 경우([bcd]) 그 뒤에 언더바(_)를 추가하는 경우다.

# b,c,d가 출현하면 바로 뒤에 언더바(_) 추가
echo "abcde" | awk '{ result=gensub(/([bcd])/, "\\1_", "g", $0); print result }'
ab_c_d_e

조건 문자열에 소괄호를 이용해서 영역을 설정하고, 이 영역을 대체할 문자열에서 \\1, \\2, 이런 식으로 가져와서 사용하게 된다. 예를 하나 더 보자. 알파벳 소문자가 나오고 연속해서 수자가 나올 경우 알파벳 소문자 뒤에 언더바를 붙이고 알파벳과 수자의 위치를 바꾸는 경우다.

# 소문자 다음에 수자가 나오면 소문자 뒤에 언더바를 붙이고 자리를 바꿈
echo "ab123c4" | awk '{ result=gensub(/([a-z])([0-9])/, "\\2\\1_", "g", $0); print result }'
a1b_234c_

알파벳 소문자([a-z])가 첫번째 영역(\\1), 수자([0-9])가 두번째 영역(\\2)이 되므로 대체할 문자열 부분에 순서를 바꾸고 첫번째 영역 뒤에 언더바(_)를 붙여주었다.("\\2\\1_").

 

728x90
Posted by 반달가면