sed를 사용하여 변수에서 여러 정규식 제거

sed를 사용하여 변수에서 여러 정규식 제거

나는 이것이 간단하다고 확신하지만 좋은 예를 찾을 수 없는 것 같습니다. 상자의 초기화 시스템을 찾기 위해 /proc/1/exe를 구문 분석하려고 합니다. Exe는 init 시스템에 대한 심볼릭 링크이지만 파일 수를 세어보면 그 안에 따옴표가 있는데 이를 제거하고 싶습니다. 안타깝게도 exe에는 일반 아포스트로피(U+0027)와 왼쪽 및 오른쪽 작은따옴표(U+2018 및 U+2019)가 표시됩니다. 시스템마다 다릅니다. 이것이 내가 실행 중인 셸 및/또는 해당 버전 때문인지, 통계 유틸리티 때문인지, 시스템 자체 때문인지는 확실하지 않습니다. 방금 이 세 문자가 모두 섞여 있는 것을 보았습니다(때때로 함께 혼합됨).

궁극적으로 동일한 sed 명령을 사용하여 이러한 문자를 모두 제거하고 싶습니다. 지금까지는 sed를 다른 sed 명령에 연결해야만 이 작업을 수행할 수 있었습니다.

전체 exe 파일은 다음과 같습니다.

$stat /proc/1/exe

  File: '/proc/1/exe' -> '/sbin/init'
  Size: 0           Blocks: 0          IO Block: 1024   symbolic link
Device: b9h/185d    Inode: 76948360    Links: 1
Access: (0777/lrwxrwxrwx)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2017-02-01 14:52:39.101744022 -0700
Modify: 2017-01-25 12:52:20.741244423 -0700
Change: 2017-01-25 12:52:20.741244423 -0700
 Birth: -

이 예에서는 일반 아포스트로피일 뿐이지만 다른 인용 문자도 본 적이 있습니다. 그래서 먼저 필요한 것을 얻습니다.

$stat /proc/1/exe | grep File: | awk -F '->' '{print $2}'
'/sbin/init'

이제 따옴표를 제거하고 싶습니다. 다양한 유형의 따옴표를 모두 제거할 수 있는 유일한 방법은 여러 sed 명령을 사용하는 것입니다.

$stat /proc/1/exe | grep File: | awk -F '->' '{print $2}' | sed 's/\xe2\x80\x98//g' | sed 's/\xe2\x80\x99//g' | sed 's/\x27//g'
 /sbin/init

그런 다음 다른 awk 문으로 파이프합니다.

$stat /proc/1/exe | grep File: | awk -F '->' '{print $2}' | sed s'/\xe2\x80\x98//g' | sed 's/\xe2\x80\x99//g' | sed 's/\x27//g' | awk -F '/' '{print $NF}'
init

나는 /proc/1/comm을 알고 있거나 /proc/1/exe에서 ls를 사용합니다. 문제는 세 개의 sed 명령을 하나로 결합하는 방법입니다. 그것은해야한다:

열기, 닫기 또는 아포스트로피가 있으면 제거하십시오. 모든 상황에서 이 작업을 수행해야 합니다.

그런데, 상자의 초기화 시스템을 가져오는 더 나은 명령(신뢰할 수 없는 /proc/1/comm 제외)을 아는 사람이 있거나 이러한 명령을 더 효율적으로 만들 수 있는 사람이 있다면 프로세스에서 배우는 데 관심이 있습니다.

답변1

다른 사람들이 지적했듯이 PID 1의 속성을 결정하는 더 좋은 방법이 있습니다. 단일 파이프라인에서 여러 호출을 사용하는 것은 거의 좋은 생각이 grep아닙니다 . 그렇게 할 수 없다면 을 사용하십시오 . ( 쉽게) 할 수 없다면 다음을 사용하십시오.sedawkgrepsedsedawk

stat /proc/1/exe | sed -n '/File:/{s/.*-> *[\xe2\x80\x98]//;s/[\xe2\x80\x99].*//p;q}'

답변2

여기서는 약간 다른 접근 방식을 취할 수 있습니다. 이는 "세 개의 sed 명령을 하나로 결합하는 방법"이라는 원래 질문을 여전히 만족시키고 명령 자체도 향상시킵니다. 의심할 바 없이 init 시스템을 검색하는 방법이라는 두 번째 문제를 해결하는 다른 방법이 많이 있습니다.

원하지 않는 것을 제거하려고 하는 대신 캡처 그룹을 사용하여 원하는 것을 캡처하고 문자 집합을 사용하여 여러 값을 일치시킬 수 있습니다. 문자 집합은 대괄호 "[]"로 표시됩니다. 내부에는 일치시키려는 항목을 정확하게 입력하면 그 사이에 암시적 OR 문이 표시됩니다. 따라서 시작 인용문과 일치하도록또는사용하는 아포스트로피:

[\xe2\x80\x98 \x27]

시작 따옴표는 "e28098" 16진수 문자이고 아포스트로피는 "27" 16진수 문자입니다. 두 개의 개별 문자를 강조하기 위해 그 사이에 공백을 넣었지만 기술적으로 이것은 시작 인용문과 일치합니다.또는공간또는아포스트로피. 일치하지 않으려면 공백을 제거하십시오. 올바른 인용문과 일치시키려면 "e28099"를 추가할 수도 있습니다.

명령 자체를 개선하고 "init" 또는 "systemd"만 가져오려면 캡처 그룹을 사용하여 다른 접근 방식을 취할 수 있습니다. 캡처 그룹은 대괄호 "( )"로 표시됩니다. 그런 다음 해당 캡처 그룹을 참조할 수 있습니다. 예를 들어, 필요한 것을 캡처하기 위해 다음 명령을 사용했습니다.

stat /proc/1/exe | sed -rn 's/^.*File:.*->.*[\xe2\x80\x98\x27]\/.*\/(.+)[\xe2\x80\x99\x27]$/\1/p'

캡처 그룹(대괄호 사이의 ".+")은 여는 따옴표 또는 아포스트로피와 닫는 따옴표 또는 아포스트로피 사이의 마지막 슬래시 이후의 모든 내용을 캡처합니다. "\1"을 사용하여 참조됩니다(첫 번째이자 유일한 캡처 그룹이기 때문입니다). Sed는 전체 줄을 캡처 그룹의 내용으로 바꿉니다.

  • -r 확장 정규식의 경우(적어도 내 버전의 sed에서는)
  • -n은 인쇄를 억제하는 데 사용됩니다. "/p" 옵션과 함께 사용하면 패턴과 일치하는 행만 인쇄되지만 패턴이 교체된 후에는 인쇄됩니다. 이렇게 하면 sed가 grep처럼 작동합니다.

이것이 다른 사람들에게 도움이 되기를 바랍니다.

관련 정보