- Published on
2025.10.17
[모두의 리눅스] - 14. 고도의 텍스트 처리
14.1. sed 명령어: 스트림 에디터
비대화형 에디터
메모장이나 Vim 등의 대화형 에디터는 파일을 열어 메모리상에서 편집하고 저장하는 형태로 파일을 편집
반면, 비대화형 에디터인 sed는 다음과 같이 동작
sed [옵션] <스크립트> <대상파일>
- 셸에서 편집 내용을 인자로 지정해
sed를 실행 sed가 편집을 수행- 완료된 내용을 표준 출력
sed는 편집한 내용을 표준 출력만 하고 원본의 내용을 바꾸지 않아 원본 파일 손상 걱정이 없음
sed의 스크립트는 주소와 명령어를 조합한 문자열로, 주소는 행을 의미하며 지정하지 않으면 모든 행이 해당.
- 행 삭제(d)
$ sed 1d example.txt # 첫 번째 행을 삭제
$ sed 2,5d example.txt # 2행부터 5행을 삭제
$ sed '3,$d' example.txt # 3행부터 마지막 행까지 삭제, $는 마지막 행을 의미
$ sed d example.txt # 모든 행을 삭제
주소는 행 번호뿐 아니라 정규 표현식도 사용할 수 있음.
$ sed /^B/d example.txt # B로 시작하는 행을 삭제
- 행 출력(p)
$ sed 1p example.txt # 첫 번째 행을 출력하지만 패턴 스페이스의 내용이 같이 출력되어 모든 내용이 출력
$ sed -n 1p example.txt # 패턴 스페이스를 제외하여 첫 번째 행만 출력(의도대로 동작)
- 행 치환(s)
s/치환 전 문자열/치환 후 문자열/옵션
$ sed 's/before/after/' example.txt # before 문자열을 after로 치환, 주소를 생략해 모든 행에 적용
$ sed 's/before/after/g' example.txt # 각 행에서 처음 발견한 문자열만 치환하기 때문에 모든 문자열을 치환하려면 g 옵션 지정
$ sed '1,3s/before/after/g' example.txt # 1행에서 3행까지만 치환, 주소 지정 가능
후방 참조
정규 표현식에서 ()를 사용해 그룹화한 뒤 \1과 같이 참조하는 것.
정규 표현식을 사용해 치환할 때 검색된 문자열의 일부를 치환하려는 경우 후방 참조를 사용
- 기본 정규 표현식:
\(\)로 그룹화하여\1로 참조 - 확장 정규 표현식:
()로 그룹화하여\1로 참조
14.2. awk 명령어: 패턴 검색 및 처리 언어
awk는 텍스트 검색, 추출, 가공 등의 편집 작업을 위한 명령어로, '오크'라고 읽음.sed처럼 편집 작업 실행 후 결과를 출력하며 입력 텍스트를 한 행씩 읽어 처리
# awk의 스크립트
패턴 {액션}
</서식>
awk는 한 행마다 패턴의 액션 실행 조건이 부합하는지를 확인함. 텍스트의 한 행을 awk에서는 레코드라고 부름.
액션에 텍스트 추출, 치환, 삭제 등의 처리를 지정해두고 패턴에 일치할 경우만 액션이 실행됨. 패턴이 없다면 모든 레코드에 액션 실행.
$ awk '{print $2, $3}' example.txt # 파일에서 2번째, 3번째 필드만 출력, 패턴이 생략되어 모든 행에 액션이 실행
$ awk '$1 ~/^s/ {print NR, $0}' example.txt # 첫 번쨰 필드가 s로 시작하는 레코드만 추출해 행 번호와 함께 출력
필드 변수
awk는 각 레코드를 필드로 자동 분리해 각각 $1···과 같이 필드 변수에 대입함. 레코드 전체는 $0에 대입. 공백이나 탭을 구분자로 필드를 분할하며, 공백이 여러 개로 이어지면 하나로 간주함.
print시, 변수를 쉼표로 구분하면 각 값 사이 공백이 표시되어 출력됨.
NF변수는 레코드의 필드 개수를 담고 있는 변수로, $NF를 print하면 마지막 필드가 출력. $(NF-1)은 마지막에서 두 번째 필드와 같이 연산을 수행할 수 있음.
패턴 지정
정규 표현식, 확장 정규 표현식을 사용할 수 있으며, 정규 표현식은 /로 감싸서 사용. 정규 표현식을 확인할 필드는 ~로 지정.
$ls -l /usr/bin | awk '$9 ~ /^cp/ {print $5, $9}' # 9번째 필드가 `/^cp/`, cp로 시작하는지 확인.
$ls -l /usr/bin | awk '/^I/ {print $5, $9}' # 필드를 지정하지 않아 레코드 전체가 정규 표현식에 해당하는지 확인.
액션 생략
액션을 생략하면 {print $0}이 실행
- awk는 변수 선언, 초기화를 하지 않고도 사용할 수 있음
- END 패턴: END 안의 액션은 모든 처리가 끝난 뒤 마지막 한 번만 실행
- NR 변수: 지금까지 읽은 레코드의 수를 담고 있음