안녕하세요, 프로젝트 배포를 위해 makefile에서 실행하는 스크립트가 있습니다. 여기에서는 sed를 사용하여 입력 문자열에서 환경과 프로젝트 이름을 캡처하고 있으며 우분투에서 훌륭하게 작동합니다.
이 간단한 명령
echo deploy-api-production | sed -E 's/deploy-\w+-(\w+)/\1/'
production
우분투에서 예상 결과를 제공합니다
우분투 실행
$ echo deploy-api-production | sed -E 's/deploy-\w+-(\w+)/\1/'
production
하지만 Mac에서는 전체 문자열을 제공합니다.deploy-api-production
맥 실행:
$ echo deploy-api-production | sed -E 's/deploy-\w+-(\w+)/\1/'
deploy-api-production
Mac에서 동일한 결과를 얻을 수 있도록 일종의 통합 sed가 있습니까?
출력이 Mac 실행의 결과물이기를 원합니다.
사례 2 - 보다 일반적이며 접두사도 포함됩니다.
이것을 올바르게 분석하고 싶습니다
echo a-deploy-api-production | someprocessing
production
so는 위의 상황과 유사하지만 a-
단어 앞에 추가 접두어 단어가 있습니다.deploy
현재 주어진 솔루션과 비슷한 것을 시도했지만 성공하지 못했습니다.
echo a-deploy-api-production | awk -F'-' '$1=="a-deploy"{print $3}'
위의 결과는 비어 있습니다. 결과를 얻기 위해 수정하고 싶습니다.production
답변1
당신은 그것을 사용할 수 있습니다 awk
:
echo deploy-api-production | awk -F'-' '$1=="deploy"{print $3}'
이렇게 하면 텍스트가 로 구분된 부분으로 분할됩니다 -
. 첫 번째 필드가 단어와 일치해야 deploy
하고 세 번째 필드가 인쇄됩니다.
업데이트된 질문에 새로운 변형이 포함되었습니다. 동일한 코드를 사용하여 awk
직접 비교할 수는 없습니다. a-deploy
이는 두 개의 필드(대시로 구분됨)와 $1
첫 번째 필드(즉, 이 새 인스턴스에는 a
없음 )만 있기 때문입니다.deploy
deploy
모든 사용 사례를 알지 못한 채 문자열의 아무 곳이나 검색하고 발견되면 마지막 필드를 인쇄하는 것이 더 좋을 것이라고 제안합니다 . (이것은 원래 케이스에도 적용됩니다.)
echo deploy-api-production | awk -F'-' '/deploy/ {print $NF}'
production
echo a-deploy-api-production | awk -F'-' '/deploy/ {print $NF}'
production
답변2
POSIX 사용-라이 sed
, 두 시나리오 모두 그림과 같이 원하는 결과를 얻을 수 있습니다.
w='[[:alpha:]][_[:alnum:]]*'
echo 'deploy-api-productionN' |
sed -n -e "/^\($w-\)\{0,1\}deploy-/s/^$w\(-\($w\)\)\{1,\}\$/\2/p"
관찰 결과:
- sed에는 단어에 대한 기호가 없으므로 이에 대한 정규식을 작성하고 이를 쉘 변수에 저장합니다.$w
- \{0,1\}은 BRE인가요?
- \{1,\}은 +의 BRE입니다.
- \(...\)는 (...)의 BRE입니다.
답변3
GNU 시스템은 PCRE
(Perl 호환 정규식). 이러한 기호(예: \s
및 \w
)는 표준 기호가 아니며 sed
모든 시스템(일반적으로 GNU 시스템 외부)에서 지원되지 않습니다.
-
줄이 하위 문자열 또는 로 시작하는 경우 deploy
마지막 줄(대시) 뒤에 줄의 마지막 부분을 출력하려는 것 같습니다 something-deploy
.
표준 방법을 사용하여 sed
이 작업을 수행할 수 있습니다.
sed '/^deploy/ s/.*-//'
또는
sed '/^something-deploy/ s/.*-//'
이러한 표현식은 이전 정규 표현식이 현재 입력 행과 일치하는 경우 sed
대체를 트리거합니다 . s/.*-//
이 교체는 마지막 대시를 포함하여 줄의 모든 것을 제거합니다.
이 경우 필요한 경우 트리거 표현식을 대체 표현식과 결합할 수 있습니다.
sed 's/^deploy.*-//'
sed 's/^something-deploy.*-//'
데이터가 (질문에서와 같이) 정적 문자열 출력이 아니고 echo
변수의 일부 값인 경우 외부 프로그램을 호출하는 것보다 쉘에서 이 작업을 수행하는 것이 더 효율적입니다.
string=deploy-api-production
if [[ $string == deploy-* ]]; then
printf '%s\n' "${string##*-}"
fi
printf
에 표시된 대로 수정된 값을 유지하려면 대신 변수 할당을 사용합니다 new=${string##*-}
.
확장은 쉘 패턴과 일치하는 ${variable##pattern}
가장 긴 접두사 문자열에서 제거됩니다 .$variable
pattern