Computer >> 컴퓨터 >  >> 프로그래밍 >> Bash 프로그래밍

고급 Sed 대체:전문 기술 및 실제 사례

고급 Sed 대체:전문 기술 및 실제 사례 이 문서는 진행 중인 Unix Sed 팁 및 요령 시리즈의 일부입니다.

이전 sed 기사에서 우리는 sed 인쇄, sed 삭제, sed 대체, sed 파일 쓰기, sed 다중 명령 등을 배웠습니다.

이 기사에서는 몇 가지 실제 예와 함께 sed에서 "s" 대체 명령을 사용하여 몇 가지 흥미로운 해결 방법을 검토해 보겠습니다.

나. Sed 대체 구분 기호

이전 게시물에서 논의한 것처럼 @% |; :sed 대체 명령에서.

먼저 아래 언급된 모든 예시에 사용될 path.txt 파일을 생성해 보겠습니다.

$ cat path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:
/opt/omni/lbin:/opt/omni/sbin:/root/bin

예 1 – sed @ 구분 기호:/opt/omni/lbin을 /opt/tools/bin으로 대체

'/'가 포함된 경로 이름을 대체하는 경우 '/' 대신 @를 구분 기호로 사용할 수 있습니다. 아래 sed 예에서는 입력 파일의 마지막 줄에서 /opt/omni/lbin이 /opt/tools/bin으로 변경되었습니다.

$ sed 's@/opt/omni/lbin@/opt/tools/bin@g' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:
/opt/tools/bin:/opt/omni/sbin:/root/bin

예 2 – sed / 구분 기호:/opt/omni/lbin을 /opt/tools/bin으로 대체

경로명 관련 대체에 '/'를 사용해야 하는 경우 아래와 같이 대체 데이터에서 '/'를 이스케이프해야 합니다. 이 sed 예에서는 REGEXP 및 REPLACEMENT 부분에서 구분 기호 '/'가 이스케이프되었습니다.

$ sed 's/\/opt\/omni\/lbin/\/opt\/tools\/bin/g' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:
/opt/tools/bin:/opt/omni/sbin:/root/bin

II. Sed '&' 일치하는 문자열 가져오기

정규식이 일치하는 입력 줄의 정확한 부분은 &로 표시되며, 이는 대체 부분에서 사용될 수 있습니다.

예 1 – sed 및 사용법:/usr/bin/을 /usr/bin/local로 대체

$ sed 's@/usr/bin@&/local@g' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin/local:/usr/sas/bin
/usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin/local:/opt/omni/bin:
/opt/omni/lbin:/opt/omni/sbin:/root/bin

위의 예에서 교체 부분의 '&'는 패턴과 일치하는 /usr/bin으로 대체되고 /local로 추가됩니다. 따라서 출력에서 /usr/bin의 모든 항목은 /usr/bin/local로 대체됩니다.

예 2 – sed &사용법:전체 줄 일치

&는 주어진 REGEXP와 일치하는 항목을 대체합니다.

$ sed 's@^.*$@<<<&>>>@g' path.txt
<<</usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin>>>
<<</usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:>>>
<<</opt/omni/lbin:/opt/omni/sbin:/root/bin>>>

위의 예에서 regexp에는 전체 줄과 일치하는 "^.*$"가 있습니다. 대체 부분 <<<&>>>은 줄의 시작과 끝에 각각 <<<및>>>을 사용하여 전체 줄을 작성합니다.

III. Sed의 그룹화 및 역참조

그룹화는 일반 정규식처럼 sed에서 사용할 수 있습니다. 그룹은 "\("로 열리고 "\)"로 닫힙니다. 그룹화는 역참조와 함께 사용할 수 있습니다.

역참조는 그룹화하여 선택한 정규식의 일부를 재사용하는 것입니다. sed의 역참조는 정규식과 대체 명령의 대체 부분 모두에서 사용될 수 있습니다.

예 1:각 줄의 첫 번째 경로만 가져오기

$ sed 's/\(\/[^:]*\).*/\1/g' path.txt
/usr/kbos/bin
/usr/local/sbin
/opt/omni/lbin

위의 예에서 \(\/[^:]*\)는 first :가 오기 전에 사용 가능한 경로와 일치합니다. \1은 일치하는 첫 번째 그룹을 대체합니다.

예 2:다중 그룹화

path.txt 파일에서 파일 마지막 줄의 필드 순서를 변경하세요.

$ sed '$s@\([^:]*\):\([^:]*\):\([^:]*\)@\3:\2:\1@g' path.txt
/usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin
/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/omni/bin:
/root/bin:/opt/omni/sbin:/opt/omni/lbin

위 명령에서 $는 마지막 줄에 대해서만 대체가 발생하도록 지정합니다. 출력에서는 마지막 줄의 경로 값 순서가 바뀌었음을 보여줍니다.

예 3:/etc/passwd 파일에서 사용자 이름 목록 가져오기

이 sed 예제는 /etc/passwd 파일의 첫 번째 필드만 표시합니다.

$sed 's/\([^:]*\).*/\1/' /etc/passwd
root
bin
daemon
adm
lp
sync
shutdown

예 4:각 단어의 첫 번째 문자를 괄호로 묶습니다.

이 sed 예제는 괄호 안의 모든 단어의 첫 번째 문자를 인쇄합니다.

$ echo "Welcome To The Geek Stuff" | sed 's/\(\b[A-Z]\)/\(\1\)/g'
(W)elcome (T)o (T)he (G)eek (S)tuff

예 5:단순 숫자를 압축합니다.

숫자 목록이 있는 숫자라는 파일을 만들어 보겠습니다. 아래 sed 명령 예는 숫자를 수천까지 압축하는 데 사용됩니다.

$ cat numbers
1234
12121
3434
123
$sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers
1,234
12,121
3,434
123