bash script2023. 4. 18. 14:55

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

 

여러 항목으로 구성된 문자열에서 특정 위치에 있는 문자열만 골라서 바꾸는 방법이다. 예를 들어 탭(tab)을 구분자로 해서 이름, 별명, 전화번호가 있을 경우 별명 항목에 있는 특정 문자열을 바꿔야 하는 경우다.

아래와 같이 my_list.txt 파일이 있다고 가정해 보자.

# my_list.txt 내용 확인: 이름, 이메일, 전화번호 - 탭으로 구분
cat my_list.txt
john  john@abc-pharm.com  123-1234
jane  jane@def.com  111-2222

위의 예시에서 전화번호의 대시(-)를 점(.)으로 바꿔야 한다고 생각해 보자. 즉 세번째 항목에 대해서만 문자열 대체를 수행해야 한다. awk 명령에서 sub 함수를 이용하면 가능하다. sub 함수의 형식은 아래와 같다.

sub("바꿀 대상 문자열", "대체할 문자열", 항목변수)

아래의 예시를 보자.

# my_list.txt에서 세번째 항목(전화번호)의 대시(-)를 점(.)으로 대체
cat my_list.txt | awk -F '\t' -v OFS='\t' '{ sub("-",".",$3); print }'
john  john@abc-pharm.com  123.1234
jane  jane@def.com  111.2222

awk 명령의 옵션을 보자. 탭으로 구분되어 있으므로 -F 옵션을 이용해서 입력되는 내용의 구분자를 탭으로 지정해 주고(-F '\t'), 출력할 때도 구분자가 탭이 되도록 -v 옵션에서 출력 구분자 변수인 OFS를 탭으로 지정했다(-v OFS='\t'). 세번째 항목($3)에 대한 문자열 대체는 sub 함수를 사용했다. 그리고 나서 print 명령으로 대체된 결과를 출력.

sub 함수에 정규표현식(regular expression)을 사용할 수도 있다. 아래의 예시를 보자.

# my_list.txt에서 두번째 항목(이메일)에 대괄호([]) 적용
cat my_list.txt | awk -F '\t' -v OFS='\t' '{ sub("^","\[",$2); sub("$","\]",$2); print }'
john  [john@abc-pharm.com]  123-1234
jane  [jane@def.com]  111-2222

sub 함수는 문자열 대체를 조건에 맞는 첫번째 문자열에 대해서만 수행한다. sub 함수를 두번 사용해서 괄호를 만들었다. 두번째 항목($2)의 시작 부분(^)을 왼쪽 대괄호([)로, 끝부분($)을 오른쪽 대괄호(])로 대체했다.

만약 해당 조건의 문자열 모두에 대해 대체를 수행하고 싶다면 gsub 함수를 사용하면 된다. 아래의 예시를 보자.

# my_list.txt에서 첫번째 항목의 첫 소문자를 0으로 대체(sub)
cat my_list.txt | awk -F '\t' -v OFS='\t' '{ sub("[a-z]","0",$1); print }'
0ohn  john@abc-pharm.com  123-1234
0ane  jane@def.com  111-2222

# my_list.txt에서 첫번째 항목의 소문자 전체를 0으로 대체(gsub)
cat my_list.txt | awk -F '\t' -v OFS='\t' '{ gsub("[a-z]","0",$1); print }'
0000  john@abc-pharm.com  123-1234
0000  jane@def.com  111-2222

형식이 고정된 파일의 특정 항목에 대해서 작업을 해야 할 경우 아주 요긴하게 활용할 수 있다.

728x90
Posted by 반달가면