일반 bash에서 regexp를 사용하여 부분 문자열 추출


97

bash를 사용하여 문자열에서 시간을 추출하려고하는데 그것을 알아내는 데 어려움을 겪고 있습니다.

내 문자열은 다음과 같습니다.

US/Central - 10:26 PM (CST)

그리고 10:26부분 을 추출하고 싶습니다 .

sed, awk 등을 사용하지 않고 bash로만이 작업을 수행하는 방법을 아는 사람이 있습니까?

마찬가지로 PHP에서 나는 최선의 방법은 아니지만 작동합니다.

preg_match( ""(\d{2}\:\d{2}) PM \(CST\)"", "US/Central - 10:26 PM (CST)", $matches );

답변에 sed 또는 awk를 사용하더라도 도움을 주셔서 감사합니다.

답변:


207

순수 사용 :

$ cat file.txt
US/Central - 10:26 PM (CST)
$ while read a b time x; do [[ $b == - ]] && echo $time; done < file.txt

bash 정규식을 사용한 또 다른 솔루션 :

$ [[ "US/Central - 10:26 PM (CST)" =~ -[[:space:]]*([0-9]{2}:[0-9]{2}) ]] &&
    echo ${BASH_REMATCH[1]}

grep고급 정규식을 사용 하고 둘러 보는 또 다른 솔루션 :

$ echo "US/Central - 10:26 PM (CST)" | grep -oP "\-\s+\K\d{2}:\d{2}"

sed를 사용하는 또 다른 솔루션 :

$ echo "US/Central - 10:26 PM (CST)" |
    sed 's/.*\- *\([0-9]\{2\}:[0-9]\{2\}\).*/\1/'

perl을 사용하는 또 다른 솔루션 :

$ echo "US/Central - 10:26 PM (CST)" |
    perl -lne 'print $& if /\-\s+\K\d{2}:\d{2}/'

마지막으로 awk 사용 :

$ echo "US/Central - 10:26 PM (CST)" |
    awk '{for (i=0; i<=NF; i++){if ($i == "-"){print $(i+1);exit}}}'

멋있는! 패턴에 하이픈 "-"도 사용할 수 있습니까? 그 그렙 어떤 경기를 반환하고 난 단지 하이픈 다음에 공백 다음 시간 .....이 사람에 관심이 있기 때문에
andrux

나는 아마도 펄 솔루션을 가질 수 있었지만 그것은 훌륭한 장점입니다. 감사!
andrux

재미를 위해 추가 된 awk 하나 =)
질 Quenot

1
\ K "트릭"을 알려 주셔서 감사합니다. perl 구문을 사용하는 grep은 정말 강력합니다.
Marco Sulla 2014 년

1
나는 sed버전을 좋아 하지만 sed반드시 +수정자를 필요로하지 않는 다른 사람들에게 경고하고 싶었다 . 해결 방법 중 하나는 {1, }수정자를 사용 하여 하나 이상을 일치시키는 것입니다.
CodeBrew

89
    echo "US/Central - 10:26 PM (CST)" | sed -n "s/^.*-\s*\(\S*\).*$/\1/p"

-n      suppress printing
s       substitute
^.*     anything at the beginning
-       up until the dash
\s*     any space characters (any whitespace character)
\(      start capture group
\S*     any non-space characters
\)      end capture group
.*$     anything at the end
\1      substitute 1st capture group for everything on line
p       print it

8
나는 이것이 나를 즉각적인 sed 마스터가 된 것처럼 느낍니다. 내가 조정할 수있는 좋은 옵션 중 하나는 내가 이해하지 못하는 9 개보다 낫다.
Noumenon

자세한 설명을 보내 주셔서 감사합니다. 향후 "XXXX를 어떻게 정규식을 지정합니까"게시물을 피하는 데 도움이됩니다.
studgeek

4
으로 먼저 인쇄를 억제 -n한 다음 다시 인쇄를 요청 하는 이유를 설명해 주 /p시겠습니까? -n플래그를 생략하고 /p지시문 을 생략하는 것이 동일하지 않습니까? 감사.
Victor Zamanian

좋은 대답! 당신의 도움 :-) 주셔서 감사합니다
브루노 Lavit

1
@VictorZamanian from here : "기본적으로 sed는 모든 줄을 인쇄합니다. 대체하면 이전 텍스트 대신 새 텍스트가 인쇄됩니다. sed에 선택적 인수를 사용하면"sed -n "은 인쇄되지 않습니다. 기본적으로 새 줄을 인쇄합니다. ... "-n"옵션을 사용하면 "p"플래그가 수정 된 줄을 인쇄합니다. "
tdashroy

26

빠르고 더럽고, 정규식이 없으며, 견고성이 낮은 찹찹 기술

string="US/Central - 10:26 PM (CST)"
etime="${string% [AP]M*}"
etime="${etime#* - }"

5
그것은 너무 역 겨울 정도로 더러워서 부끄럽습니다. +1도 | read zone dash time apm zone작동합니다
Orwellophile 2015-04-30

매우 깨끗하고 외부 프로그램에 대한 호출을 피합니다.
Victor Zamanian

8
안녕하세요, 사람들이 더 많이 연구 할 수 있도록 추가 문서에 대한 참조 또는 기술에 대한 일부 이름을 포함하면 10 배 더 유용 할 것입니다. 관심 들어,이 bash는 문자열 조작, 당신은 여기에서 자세한 내용을 찾을 수 있습니다 tldp.org/LDP/abs/html/string-manipulation.html
페드로 마타 Mouros

0

당신의 문자열이

foo="US/Central - 10:26 PM (CST)"

그때

echo "${foo}" | cut -d ' ' -f3

일을 할 것입니다.


1
또는 cut -c14-18물론 캐릭터 위치가 변경되지 않는 한. 시간대가 고정 된 경우에는 발생하지 않아야합니다.
Markus

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