리눅스에서 grep 명령과 비슷하게 사용할 수 있는 sed 명령어, 익숙하지는 않지만 사용방법에 대해서 어느 정도 알고 있다면 리눅스에서 파일을 관리하거나 원하는 데이터를 추출하는 데 있어서 도움이 될 수 있습니다. 이번에는 sed 명령어의 예시를 들어 사용방법을 알아보고자 합니다.
sed (Stream Editor) 명령어의 사용방법
sed 명령어는 편집기와 비슷합니다. vi 편집기처럼 원하는 문자열을 치환하는 등 다양한 작업을 수행할 수 있습니다. 어떤 파일에서 원하는 내용을 추출하거나, 치환하는 작업을 수행할 수 있습니다. 원본 파일 자체를 변경하는 옵션도 있지만, 이번에는 파일에서 조건에 맞는 내용으로 추출하는데 중점을 두려고 합니다.
sed 명령어는 두 가지 버퍼를 가지고 있습니다. 하나는 홀드 버퍼라고 불리며 데이터의 원본을 가지고 있는 곳입니다. 다른 하나는 패턴 버퍼 라고 불리며 조건에 따라 가공된 데이터가 저장됩니다.
명령어를 사용하면 파일을 횡 단위로 구분하여 하나의 행을 가지고 온 뒤 원본 데이터를 저장하고 조건에 맞는 필터를 거쳐 패턴 버퍼에 저장합니다.
처음 사용하면 어렵게 느껴질 수 있습니다. 자주 사용하는 명령어의 방식과 사용했을 때 예시를 통해 어떻게 패턴이 적용되어 변화하는지 확인할 수 있습니다.
자주 사용하는 sed 명령어 사용 예시
]# sed '[패턴]' [파일명]
]# cat [파일명] | sed '[패턴]'
어떤 파일에서 sed 명령을 이용해 특정 패턴을 적용하여 추출 된 데이터를 확인할 수 있습니다. 또한 cat 명령으로 파일을 확인한 뒤 파이프라인 ( | )을 이용해 패턴을 적용할 수 있습니다.
※ 파이프라인 : Shift + \ (역슬러쉬 or 달러표시) = |
파이프라인은 바로 앞 명령의 결과물에 다른 명령을 그대로 적용하고자 할 때 사용합니다., 여기서는 cat를 이용해 확인한 파일의 결과에서 sed 명령을 통해 패턴을 적용할 수 있습니다. 또한 파이프라인을 통해 sed 명령어를 중복하여 패턴을 여러 개 적용할 수도 있습니다.
※ sed 중복적용 예시
]$ cat [파일명] | sed '[패턴]' | sed '[패턴]' | sed '[패턴]'
※ 자주 사용하는 sed 명령어 예시
명령어 예시 | 설명 (test.txt 파일에서 ~ ) |
sed '/a/d' test.txt | a가 포함된 행 삭제 |
sed 's/a//g' test.txt | a가 포함된 행에서 a만 지우고 출력 |
sed 's/ //g' test.txt | 행에서 공백(space) 제거 |
sed '/^$/d' test.txt | space 조차 없는 빈 행 삭제 |
sed '/^\s*$/d' test.txt | space만 있는 빈 행이라면 해당 행 삭제 |
sed 'a\\' test.txt | 행마다 위,아래 공백인 행 추가 |
sed 's/a.*b//' | 각 행에서 a ~ b 까지 전체 내용 삭제 후 출력 |
sed 's/\[//g' | 특수문자인 대괄호 '[' 삭제 (역슬러시 or 달러표시 사용) |
cat 명령어를 이용해 원본 파일 file.log 확인
sed 명령어는 행마다 특정 패턴을 적용하여 원하는 내용만 출력하거나, 치환하여 데이터를 추출할 수 있습니다. 명령어를 사용하기 전에 먼저 원본 파일의 내용을 확인하였습니다.
행마다 중복되어 사용된 문자열도 있으며 빈행도 존재하는 것을 확인할 수 있습니다.
1. 문자열이 들어간 행 삭제 후 출력
]# sed '/--norc/d'
= --norc가 들어간 행 삭제
원본 파일에서 특정 문자열이 들어간 행 자체를 삭제한 뒤 출력해주는 명령어 입니다. '--norc'가 들어간 행이 삭제되고 남은 내용만 출력되는 것을 확인할 수 있습니다.
이 명령은 grep -v "--norc"의 출력과 동일한 결과를 가지고 올 수 있습니다. 파일 안에서 원하는 행을 제거하고 싶거나, 특정 내용만 별도로 출력하여 다른 파일로 저장해야 하는 경우 유용하게 사용할 수 있습니다.
※ 특정 행 삭제 후 다른 파일로 저장하기
grep -v "--norc" >> test.txt
sed '/--norc/d' >> test.txt
= --norc가 들어간 행 삭제 후 test.txt 파일로 저장
2. 행에서 특정 문자열만 삭제 후 출력하기
]# sed 's/--norc//g'
= --norc가 들어간 행에서 해당 문자열만 삭제 후 출력
1번과 다르게 행 전체를 삭제하는 것이 아닌, 특정 문자만 제거한 뒤 출력해주는 명령어 입니다. grep으로는 이와 같은 작업을 하기에 어려움이 있습니다.
※ sed 's/--norc//g'
= sed 's/값 1/값 2/g'
= 값 1을 값2로 치환
위 명령을 해석해보면 특정 문자열을 다른 값으로 치환한다는 의미가 있습니다. 이를 사용하게 되면 값1을 전부 찾아 값2로 바꿔줄 수 있습니다.
위에 '--norc'를 제거하기 위해 사용했던 방식도 이와 동일합니다. 값1 자리에 --norc가 들어있으며 값2 자리에는 아무것도 없습니다. 따라서 --norc를 아무것도 없는 값으로 치환되며 이는 삭제되는 것을 말합니다.
3. 행에서 모든 공백을 제거하는 방법
]# sed 's/ //g'
= space를 삭제한 뒤 출력
2번과 같은 방식을 이용해 문자 사이의 공백을 제거할 수 있습니다. 문자 사이의 공백은 보통 space로 이루어져 있습니다.
문자가 들어갈 값1 자리에 띄어쓰기(space)를 넣어 사용한다면 해당 행에 있는 모든 space를 없는 값으로 치환하여 공백을 제거할 수 있습니다.
4. 문자열을 다른 문자열로 치환하기
]# sed 's/--norc/--test/g'
= --norc를 --test로 치환하기
2,3번과 같은 의미로 특정 문자를 다른 문자열로 치환할 수 있습니다. 여기서는 '--norc'를 '--test'로 치환하였습니다.
vim 편집기를 이용하더라도 문자열을 다른 문자로 치환할 수 있습니다. vim 편집기를 이용하는 경우에는 원본 파일을 수정하여 하나하나 확인하면서 문자열을 치환할 수 있습니다.
sed를 사용한다면 원본 파일은 그대로 두고 치환된 결과물만 바로 확인할 수 있습니다. 문자열이 같은 부분이라면 의도치 않은 부분이 치환될 수 있으니 주의해야 합니다.
또한 치환된 결과물을 바탕으로 별도의 파일을 새로 만들어 저장할 수 있습니다. sed를 사용하여 치환된 결과물을 확인한 뒤 원하는 데이터가 나왔다면 '<, >'를 이용하여 파일로 저장이 가능합니다.
※ sed 's/--norc/--test/g' >> test.txt
= --norc를 --test로 바꾼 뒤 결과물을 test.txt 파일을 만들어 저장
5. 문자열부터 다음 문자열까지 사이의 내용을 모두 삭제 or 치환하기
]# sed 's/running.*--norc/ /g'
= running부터 --norc까지의 모두 삭제
단순한 문자열 하나가 아닌, 두 개의 문자열을 사용하여 그 사이의 내용을 모두 삭제하거나 다른 값으로 치환할 수 있습니다. 위에서는 running ~ --norc까지의 내용을 모두 space로 치환하였습니다.
※ sed 's/running.*--norc/ /g'
= sed 's/값 1.*값 2/ /g'
두 문자열은 마침표 (.)로 구분할 수 있으며 그 사이 모든 내용을 의미하는 기호인 *를 사용하였습니다. 따라서 두 문자열 사이에 어떤 값이 들어있던 모든 값을 포함한다는 의미가 됩니다.
또한 어떤 값으로 치환할지 지정하는 자리에 space가 들어있습니다. (/ /g) 추출된 결과물을 보면 running부터 --norc까지의 내용이 사라지고 공백 (space)으로 바뀐 것을 확인할 수 있습니다.
5-1 따옴표 사이의 모든 내용 삭제하기
]# sed 's/".*"//'
= 따옴표 " " 사이의 내용 모두 삭제
5번과 동일한 내용입니다. 다만 이번에는 뒷부분의 g를 붙이지 않았는데도 따옴표 사이의 내용이 모두 삭제된 것을 확인할 수 있습니다.
원본 파일을 보면 행의 뒤쪽에 있는 " " 사이에는 서로 다른 값이 들어있는 행도 있습니다. 하지만 의미 없이 모두 삭제된 것을 확인할 수 있습니다.
6. 두 개의 문자열을 한 번에 삭제하기
원본 파일은 tmp 이름을 가진 다른 파일을 이용했으며 "cat tmp" 명령으로 확인하였습니다.
]# sed 's/running:\|--norc/ /g'
= running: 와 --norc 두 개의 문자열 삭제 후 출력
sed를 사용할 때 꼭 한 번에 하나의 문자만 사용할 필요는 없습니다. 역 슬러시 (\)와 파이프라인 (|)을 이용하면 두 개의 문자열을 한 번에 패턴에 적용할 수 있습니다. 명령어를 적용한 결과를 보면 두 가지의 문자열이 동시에 삭제된 것을 확인할 수 있습니다.
※ sed 's/running:\|--norc/ /g'
= sed' s/값 1\|값 2/ /g''
두 개의 문자열은 (역 슬러시 + 파이프라인 = \|)으로 구분할 수 있으며 문자열이 들어가야 하는 자리에 여러 개의 문자열을 지정할 수 있습니다. 두 개뿐만 아니라 개수는 제한이 없습니다.
7. 행에 특수기호가 있는 경우, 역 슬러시를 이용해 삭제하기
]# sed 's/\[\|\]/ /g'
= 특수기호인 대괄호 '[, ]'만 제거 후 출력
특수기호를 제거하기 위해서는 그 앞에 역슬러시 또는 달러표시를 붙여야 합니다. 위에서는 역슬러시를 이용해 대괄호를 제거하였습니다.
※ sed 's/\[\|\]/ /g'
\[ = 대괄호 열기
\| = 두 개의 문자를 사용하기 위한 역슬러시 + 파이프라인
\] = 대괄호 닫기
= 열고 닫는 대괄호 문자 두 개를 한 번에 삭제 : \[\|\]
두 개의 대괄호를 한 번에 지우기 위해서 역 슬러시 + 파이프라인을 사용하였으며 제거 시에는 공백으로 치환하였습니다. 결과물을 보면 대괄호가 있던 자리를 space가 채우고 있는 것을 확인할 수 있습니다.
8. 특수문자 사이에 있는 내용 모두 삭제
]# sed 's/\[.*\]//g'
= 대괄호 '[, ]' 사이 내용 모두 삭제
특수문자도 일반 문자열과 마찬가지로 두 문자 사이의 내용 전체를 지정할 수 있습니다. 모든 내용을 의미하는 기호 *를 이용해 그 사이 어떤 내용이 있더라도 모두 제거할 수 있습니다.
이번에는 공백인 space로 치환하지 않고 아예 공간 자체를 제거하였으며 대괄호가 있던 자리가 모두 사라진 것을 확인할 수 있습니다.
9. 빈행과 space가 있는 행의 차이 구분하기
빈 행에는 실제로 아무런 값이 없는 행과, space로 존재하는 행 두 가지가 있습니다.
Enter를 입력하여 다음 행으로 내려가면 그 행은 아무런 값이 없는 게 아니라 space로 이루어진 행입니다. 이를 구분하기에 앞서 먼저, 행별로 사이사이에 빈 행을 추가하여 보았습니다.
]# sed 'a\\' >> test2
= 행별로 그 사이 빈행을 하나씩 추가하여 test2 파일로 저장하기
위 명령을 사용한 결과, 행별로 빈 행이 하나씩 추가된 것을 확인할 수 있습니다. 이는 기존에 비어있는 것처럼 보이는 행의 위,아래에도 추가되어 결과적으로는 3개의 빈 행이 연속되어 있는 것으로 보입니다.
여기서 추가된 행 들은 아무런 값이 없는 (space조차 없는) 곳입니다. 이처럼 아무런 값이 없는 빈 행들은 [sed '/^$/d'] 명령어를 사용하여 제거할 수 있습니다.
※ sed 'a\\' ='a값 1'
만약 행 사이에 빈행이 아니라 다른 값을 추가하고 싶다면 값 1 자리에 원하는 문자열을 넣어 사용할 수 있습니다. 이후 빈행이 추가된 내용을 test2 파일로 저장하여 cat 명령을 통해 확인해보았습니다.
9-1. 값이 없는, 완전히 비어있는 행 제거하기
]# sed '/^$/d'
= 빈 행 제거
위 (sed 'a\\') 명령으로 빈 행을 추가해 저장했던 test2 파일에서 빈 행을 다시 제거해보았습니다. 추가하였던 빈 행이 모두 사라지면서 원본 파일과 동일한 모습으로 돌아온 것을 확인할 수 있습니다.
다만, 이 명령으로는 기존에 가지고 있던 빈 행 3개는 사라지지 않고 그대로 남아있습니다. 이 행들은 빈행이 아니라 space가 존재하여 공백이라는 값을 가지고 있는 행이기 때문입니다. 공백을 가지고 있는 행은 다른 명령을 이용해 제거해야 합니다.
9-2. 공백 (space)으로 이루어진 빈 행 제거하기
]# sed '/^\s*$/d'
]# sed '/^[[:space:]]*$/d'
= 공백 (space)으로 이루어진 행 제거 후 출력
두 가지 명령을 이용해 공백을 가진 행을 제거해보았습니다. 두 명령 모두 같은 결과를 보여주는 것을 알 수 있습니다.
이처럼 완전히 아무런 값이 없는 빈 행이 아닌, 공백의 행을 제거하기 위해서는 sed 명령을 이용해 space으로만 이루어진 행을 제거하겠다는 패턴을 가지고 있어야 합니다.
'개인 > 리눅스' 카테고리의 다른 글
[리눅스] awk 명령어의 기본적인 사용방법 (print 함수) (0) | 2024.06.20 |
---|---|
[리눅스] sed 명령어의 기본적인 사용방법 두번째 (0) | 2023.05.03 |
[리눅스]for 문 한줄로 사용하기 (0) | 2020.04.29 |
[리눅스] grep 명령어의 기본적인 사용방법 (0) | 2020.03.22 |
[리눅스] VNC란? 사용목적과 설치 (0) | 2020.02.29 |