Linux command - sed

sycho·2024년 1월 2일
0

Linux Commands

목록 보기
20/30

sed 간략 설명

  • documentation (GNU 기반). 여기서는 기본적인 것만 알아볼 것이다.

  • Stream Editor의 줄임말이다.

  • input stream, 그러니까 사용자 입력값이나 주어진 파일에 대해서 특정 문자열을 검색, 텍스트 대체, 삽입 및 삭제를 할 때 사용되는 명령어이다.

  • VI(혹은 VIM)등의 텍스트 편집용 툴을 사용하지 않고 파일 편집이 가능하다는 것이 주된 특징이다. 이 때문에 엄청 큰 크기의 텍스트 파일의 조작에 매우 유용하다.

기본꼴

  • 이후 예제들에서 사용하는 파일은 다음과 같다.
$ cat example1.txt
sed is a stream editor.
A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed), sed works by making only one pass over the input(s), and is consequently more efficient.
But it is sed’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.

$ cat example2.txt
Linux. I love linux! I REALLY love linux!
Ubuntu...? Ubuntu linux? Linux ubuntu? Linux linux!
  • 기본 꼴은 다음과 같다.
sed OPTIONS... [SCRIPT] [INPUTFILE]
  • OPTIONS : sed서 사용할 옵션.

  • SCRIPT : sed에서 수행할 프로그램. 하나 이상의 sed command로 이루어져있다.

  • INPUTFILE : 처리할 input stream

문자열 대체 (sed s command)

  • sed command는 정말 많은걸 할 수 있지만, 가장 많이 쓰이는 기능은 역시 파일 편집관련 기능 중 하나인 문자열 대체 기능이며 이것에 대해 집중적으로 알아볼 것이다. 이는 s command가 담당한다.

  • s command는 꼴이 다음과 같다.

's/regexp/replacement/flags'
  • s : s command임을 지칭.

  • regexp : regular expression address. 보통은 그냥 regular expression이 들어가나 다른 형태도 들어가는게 가능하다. 이는 다음 글 참고

  • replacement : regexp에 따라 일치하는 부분을 발견시 이 문자열로 대체.

  • flags : 몇가지 추가 option들을 지정하는데 사용.

  • 자세한건 s command 관련 doc을 보도록 하자.

  • 유의사항으로, 기본적으로 seds command는 \n으로 구별된 각 문장의 맨 첫번째 regex 만족 문자열만 대체를 한다는 것이다. 여러개가 존재할 경우에도 첫번째에 대해서만 대체를 한다.

  • 앞의 예시 글의 sedlol로 바꾸고 싶다고 해보자. 그러면 다음과 같이 사용하면 sedlol로 바꾸는것...처럼 보인다.

$ sed 's/sed/lol/' example1.txt
lol is a stream editor.
A stream editor is ulol to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed), lol works by making only one pass over the input(s), and is consequently more efficient.
But it is lol’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.
  • 문자열 제거를 하고 싶다면 다음과 같이 하자.
$ sed 's/sed//' example1.txt
 is a stream editor.
A stream editor is u to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed),  works by making only one pass over the input(s), and is consequently more efficient.
But it is ’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.
  • exmple2.txt에서 linuxunix로 바꾸려 한 예제. 보시다시피 각 \n으로 구별된 문장의 맨 첫번째 조건 만족 문자열만 바꿔졌다.
$ sed 's/linux/unix/' example2.txt
Linux. I love unix! I REALLY love linux!
Ubuntu...? Ubuntu unix? Linux ubuntu? Linux linux!

sed 수행 결과를 input 파일에 반영 (-i)

  • 하지만 앞의 결과물이 파일에 저장되었는지 확인해보면 안되어 있다.
$ cat example1.txt
sed is a stream editor.
A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed), sed works by making only one pass over the input(s), and is consequently more efficient.
But it is sed’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.
  • 파일에 반영되게 하려면 두 가지 방법이 있다. 첫번째는 그냥 새로운 파일에 redirection을 하는 것이다.
$ sed 's/sed/lol/' example1.txt > example2.txt
$ cat example2.txt
lol is a stream editor.
A stream editor is ulol to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed), lol works by making only one pass over the input(s), and is consequently more efficient.
But it is lol’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.
  • 하지만 이는 추천하는 방법이 아니다. 원본 파일에다가 redirection으로 덮어쓰는 것이 불가능하기 때문이다. 즉 밑의 command 동작이 불가능하다는건데, 이유는 redirection 진행시 먼저 해당 파일을 열고 전부 초기화를 하기 때문에 이후 sed측에서 해당 파일을 읽고 변조시키는 것이 불가능하기 때문이다.

  • 그렇다고 위에처럼 다른 파일에 redirection을 계속 하기에는 매번 이렇게 새로운 파일 이름을 지정하는 것이 매우 번거로울 수 있다. 이 때문에 sed에서는 -i를 통해 수행한 결과물을 저장하는 것을 지원해준다.

$ sed -i 's/sed/lol/' example1.txt
$ cat example1.txt
lol is a stream editor.
A stream editor is ulol to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed), lol works by making only one pass over the input(s), and is consequently more efficient.
But it is lol’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.
  • s command뿐만 아니라 다른 모든 sed 관련 command도 이와 같이 행동하니, 결과물을 입력 파일에 그대로 반영하고 싶으면 -i를 쓰도록 하자.

delimeter 활용

  • seds command에서 s 다음에 오는 character을 delimeter이라고 한다. 보통은 /을 사용하며, 앞의 예시들도 그랬다. 그리고 이것은 다른 character로 바꾸는 것도 가능하다.
$ sed 's sed lol ' example1.txt --> delimeter이 공백인 경우
lol is a stream editor.
A stream editor is ulol to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed), lol works by making only one pass over the input(s), and is consequently more efficient.
But it is lol’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.
$ sed 's|sed|lol|' example1.txt --> delimeter이 '|'인 경우.
lol is a stream editor.
A stream editor is ulol to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed), lol works by making only one pass over the input(s), and is consequently more efficient.
But it is lol’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.
  • 앞에 말했듯 delimeter은 어지간하면 /을 사용하면 된다. 문제는 우리가 바꾸고 싶은 문자열에서 /을 포함한다고 해보자. escape character을 활용하는 방법도 있으나 사실 이 경우 delimeter을 그냥 탐색에 사용하지 않는 character로 바꾸면 된다.

  • 예시로 다음 예제를 만들어보도록 하자.

$ find /etc -type f > paths.txt
find: ‘/etc/polkit-1/localauthority’: Permission denied
find: ‘/etc/ssl/private’: Permission denied
$ cat paths.txt
/etc/services
/etc/lsb-release
/etc/protocols
/etc/rsyslog.conf
/etc/ltrace.conf
...
  • 여기서 /etc를 아예 없애버리고 싶다고 해보자. /을 사용하면 안된다.
$ sed 's//etc//' paths.txt
sed: -e expression #1, char 8: unknown option to `s'
  • 하지만 delimeter을 바꾸면 잘 된다.
$ sed 's|/etc||' paths.txt
/services
/lsb-release
/protocols
/rsyslog.conf
/ltrace.conf

각 문장에서 n번째로 조건 만족하는 문자열 바꾸기.

  • flags 부분에 숫자를 넣어가지고 각 \n으로 구별되는 문장마다 n번째로 조건을 만족하는 문자열을 바꾸는게 가능하다.
$ sed 's/linux/unix/2' example2.txt
Linux. I love linux! I REALLY love unix!
Ubuntu...? Ubuntu linux? Linux ubuntu? Linux unix!

문장의 모든 조건만족하는 문자열 바꾸기 (g flag)

  • flags부분에 g를 넣으면 문장의 모든 조건 만족 문자열들을 원하는 문자열로 바꾸는게 가능하다.
$ sed 's/linux/unix/g' example2.txt
Linux. I love unix! I REALLY love unix!
Ubuntu...? Ubuntu unix? Linux ubuntu? Linux unix!

각 문장에서 n번째 이후의 모든 조건 만족하는 문자열들 바꾸기

  • flags에 숫자랑 g를 함께 조합해서 각 \n으로 구별되는 문장의 n번째 이후의 조건 만족 문자열을 바꾸는게 가능하다.
$ sed 's/?/!/2g' example2.txt
Linux. I love linux! I REALLY love linux!
Ubuntu...? Ubuntu linux! Linux ubuntu! Linux linux!

특정 문장에 대해서 조건만족하는 문자열 바꾸기

  • s command 앞에 숫자를 통해 몇번째 문장에 대해서 조건을 만족하는 문자열을 바꿀지 지정하는 것이 가능하다.
$ sed '1 s/linux/unix/' example2.txt
Linux. I love unix! I REALLY love linux!
Ubuntu...? Ubuntu linux? Linux ubuntu? Linux linux!

특정 범위의 문장에 대해서 조건만족하는 문자열 바꾸기

  • s command 앞에 숫자 2개를 , 양옆에 둠으로써 어떤 범위의 문장에 대해서 조건을 만족하는 문자열을 바꿀지 지정하는 것이 가능하다.
$ sed '2,3 s/sed//' example1.txt
sed is a stream editor.
A stream editor is u to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed),  works by making only one pass over the input(s), and is consequently more efficient.
But it is sed’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.
  • $을 사용해서 마지막 줄을 나타내는 것이 가능하다.
$ sed '3,$ s/sed//' example1.txt
sed is a stream editor.
A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed),  works by making only one pass over the input(s), and is consequently more efficient.
But it is ’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.

줄 삭제 (d command)

  • d command도 자주 쓰이는데, 줄을 삭제할 때 쓰인다.

  • 4번째 줄을 삭제할거면 다음과 같이 쓴다.

$ sed '4d' example1.txt
sed is a stream editor.
A stream editor is used to perform basic text transformations on an input stream (a file or input from a pipeline).
While in some ways similar to an editor which permits scripted edits (such as ed), sed works by making only one pass over the input(s), and is consequently more efficient.
  • 마지막 줄을 삭제할거면 다음과 같이 쓴다.
$ sed '$d' example2.txt
Linux. I love linux! I REALLY love linux!
  • 2~3번째 줄을 삭제할거면 다음과 같이 쓴다.
$ sed '2,3d' example1.txt
sed is a stream editor.
But it is sed’s ability to filter text in a pipeline which particularly distinguishes it from other types of editors.
  • 2~마지막 줄을 삭제할거면 다음과 같이 쓴다.
$ sed '2,$d' example1.txt
sed is a stream editor.
  • 특정 패턴을 포함하는 줄을 삭제할거면 s처럼 regular expression pattern을 delimeter 사이에 넣으면 된다. 밑은 예시.
$ sed '/?/d' example2.txt
Linux. I love linux! I REALLY love linux!

변동 된 문장만 출력 (-n 과 p flag)

  • 변동이 이루어진 문장만 출력할거면 -np flag를 조합하면 된다.
$ sed -n 's/?/!/p' example2.txt
Ubuntu...! Ubuntu linux? Linux ubuntu? Linux linux!
profile
CS 학부생, 핵심 관심 분야 : Embed/System/Architecture/SWE

0개의 댓글