"echo $ x | sed…”및“echo $ x | grep…”


14

나는 종종 이것을 스크립트에서 발견합니다 (그리고 그것을 스스로 인정해야합니다) :

a=$(echo "$x" | sed "s/foo/bar/")

또는

if echo "$x" | grep -q foo
then
    ...
fi

정규 표현식을 포함하려면 "foo"를 고려하십시오.

나는이 있어야한다고 생각 - 그리고 대부분 입니다 - 구이 두 명령과 파이프를 포함하지만, 좀 더 컴팩트 식으로 일을 래핑하지 않는 하나 더 좋은 방법.

나는 그것을 찾을 수 없습니다. 아무도?


나는이 표현이 무지 (대안을 모름)와 유지 보수성 (대안을 알고 있지만 이것을 이해하기 쉬운 것으로 선택)의 조합으로 인해 자주 사용되기를 기대합니다. 나는 당신의 예제가 무엇을 한눈에 알 수 있지만 grawity와 Dan McG의 답변에서 대안을 찾기 위해 쉘 참조가 필요합니다.
quack quixote

3
그건 그렇고, 명령 대체를 선호하는 방법은 $()백틱보다 오히려입니다.
추후 공지가있을 때까지 일시 중지되었습니다.

2
공백이 보호되도록 확장을 인용하는 것도 좋습니다 : a="$(echo "$x" | sed "s/foo/bar/")"if echo "$x" | grep foo; ….
Chris Johnsen

$ () vs.``에 대한 좋은 언급. 내 bash 기술이 아직 그렇게 좋지 않다는 것을 알았습니다.
DevSolar

답변:


12

특정 쉘을 가정하지 않는 한, "파이프 에코 투 툴"(또는 expr 과 같은 "툴"자체 ) 보다 더 좋은 방법은 없습니다 . 전통적인 Bourne 쉘 및 / 또는 POSIX 쉘로 실제로 믿을 수있는 전부 입니다. 다른 쉘을 고려하면 다른 내장 가능성이 있습니다.

ksh

  • 추가 패턴 ?(pattern-list), *(pattern-list), {n}(pattern-list), {n,m}(pattern-list), @(pattern-list), !(pattern-list),
  • %P 의 printf 지정자 (및 패턴으로 확장 정규식을 변환하는 %R패턴 확장 정규식);
  • expr == pattern의 조건 [[ expr ]]시험;
  • ${param/pattern/replacement}매개 변수 확장.

bash

  • kshextglob 의 추가 패턴 대부분을 활성화 하는 옵션 (no 및 );{n}{n,m}
  • expr == pattern(조건의 [[ expr ]]검사);
  • ${param/pattern/replacement}파라미터 확장;
  • 확장 된 정규식과 일치 할 수 있는 expr =~ extregexp조건 ( [[ expr ]]테스트)
    • 괄호로 묶인 하위 표현식과 BASH_REMATCH매개 변수를 사용하여 sed 스타일 대체를 수행 할 수 있습니다.

zsh

  • EXTENDED_GLOB옵션 이있는 자체 확장 패턴 ;
  • KSH_GLOB옵션 이있는 ksh 와 같은 확장 패턴 ;
  • expr == pattern(조건의 [[ expr ]]검사);
  • ${pattern/pattern/replacement}파라미터 확장;
  • 확장 정규 표현식과 일치 할 수 있는 expr =~ extregexp조건 ( [[ expr ]]테스트 중)
    • RE_MATCH_PCRE 옵션이 설정된 경우 일반 확장 정규식 대신 PCRE 를 사용할 수 있습니다 .
    • 괄호 부분 식의와 MATCH매개 변수 및 match매개 변수 (또는 BASH_REMATCHBASH_REMATCH옵션 설정), 나오지 스타일의 교체는 할 수있다;
  • zsh/pcre모듈이 제공 pcre_compile, pcre_studypcre_match명령 및 -pcre-match 테스트 (조건의 [[ expr ]]검사);
  • 테스트 조건 zsh/regex을 제공 하는 모듈 ( 테스트 중)-regex-match [[ expr ]]

와. 원하는대로 완성하십시오. 확실히 승자.
DevSolar

6

sed 라인을 교체하려면 다음과 같이하십시오.

${a/foo/bar} 또는 ${a//foo/bar}

첫 번째 양식에서는 첫 번째 인스턴스 만 바뀝니다. 두 번째 형태는 전역 검색 및 교체입니다.

귀하의 경우에는

대신에:

if echo $x | grep foo
then
    ...
fi

다음을 사용하십시오.

if [ $x =~ foo ]
then
    ...
fi

foo정규식은 어디에 있습니까 ?


어떤 포탄에서 작동합니까?
Peltier

1
if [ $x =~ foo ]여기에 오류 메시지가 표시됩니다. if [[ $x =~ foo ]]그러나 훌륭하게 작동합니다. 감사!
DevSolar

1
이것들은 모두 bashism이며 bash가 필요합니다. 또한 =~bash> = 3 iirc가 필요합니다.
ℝaphink

1
Iirc도 foo는 이러한 예에서 PCRE에서와 같이 정규식이 아니지만 와일드 카드를 사용합니다. bash 맨 페이지의 "매개 변수 확장"섹션에 이러한 bash 장점이 더 있습니다. 나는 특히 같은 것들을 감사 ${a##foo}하고 ${a%%bar}.
ℝaphink

3
일치 연산자 =~는 정규식을 사용합니다. 예를 들면 다음과 같습니다. [[ "abcdddde" =~ ^a.*d+.g* ]]( 예를 들어 g- 와일드 카드가 아닌 0 이상의 g입니다).
추후 공지가있을 때까지 일시 중지되었습니다.

2

변수에 패턴이 포함되어 있는지 테스트하기위한 posix 호환 방법은 다음과 같습니다.

test ${var##*foo*} || <do something>;

매개 변수 확장 구문 은 다음과 같습니다.

 ${parameter##pattern}

쉘 패턴pattern 은 어디에 있습니까 ?

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.