Grep RegEx로부터의 그룹 캡처
난 이 작은 대본이 있어sh
(Mac OSX 10.6).구글에 접속합니다.
files="*.jpg"
for f in $files
do
echo $f | grep -oEi '[0-9]+_([a-z]+)_[0-9a-z]*'
name=$?
echo $name
done
에게는)$name
, 1을 2로 할 것인가에 0,1할인가?grep
파일명이 제공된 내용과 일치함을 발견했습니다.제가 원하는 것은 parens 안에 있는 것을 캡처해서 변수에 저장하는 것입니다.
가능하면 사용만 하고 싶습니다.그렇지 않은 경우 Python이나 Perl 등은 사용하지 마십시오. sed
뭐 비슷한 것 – 저는 *nix purist의 관점에서 이것을 공격하고 싶습니다.
또, 슈퍼 쿨 보너스로 셸에 실을 어떻게 연결할 수 있는지 궁금하네요.캡처한 그룹이 $name에 저장되어 있는 문자열 "somename"이고, 그 끝에 문자열 ".jpg"를 추가하고 싶은데 괜찮겠습니까?cat $name '.jpg'
Bash를한다면 Bash를 .grep
:
files="*.jpg"
regex="[0-9]+_([a-z]+)_[0-9a-z]*"
for f in $files # unquoted in order to allow the glob to expand
do
if [[ $f =~ $regex ]]
then
name="${BASH_REMATCH[1]}"
echo "${name}.jpg" # concatenate strings
name="${name}.jpg" # same thing stored in a variable
else
echo "$f doesn't match" >&2 # this could get noisy if there are a lot of non-matching files
fi
done
변수에 정규식을 넣는 것이 좋습니다.문자 그대로 포함하면 작동하지 않는 패턴도 있습니다.
은 「」를 사용합니다.=~
Bash re regex 。는 the치음음음음음음음음음음음 called called called called called called the라는 배열에 됩니다.$BASH_REMATCH
에, 그룹은0으로 하다
앵커가 경우 이 regex(및 """를 하는 regex에 .grep
는 다음 중 그 예제를 찾을 수 ( ) 、 , 、 음 、 음 、 음 、 다 、 다 、 다 、 다 ) 、 ) ) ) ) ) ) ) ) ) 。이 예에서는, 필요한 것은 아닐 수 있습니다.
123_abc_d4e5
xyz123_abc_d4e5
123_abc_d4e5.xyz
xyz123_abc_d4e5.xyz
두 번째와 네 번째 예를 제거하려면 정규식을 다음과 같이 만듭니다.
^[0-9]+_([a-z]+)_[0-9a-z]*
즉, 문자열은 1자리 이상의 숫자로 시작해야 합니다.캐럿은 현의 시작을 나타냅니다.정규식 끝에 달러 기호를 추가하면 다음과 같이 됩니다.
^[0-9]+_([a-z]+)_[0-9a-z]*$
세 번째 예시는 도트가 정규식 문자 사이에 없고 달러 기호는 문자열의 끝을 나타내기 때문에 삭제됩니다.네 번째 예도 이 일치에 실패하는 것에 주의해 주세요.
GNU가 grep
5 (2.5 의 경우), (2.5 의 경우), (2.5 의 경우)\K
(미국의
name=$(echo "$f" | grep -Po '(?i)[0-9]+_\K[a-z]+(?=_[0-9a-z]*)').jpg
\K
연산자(반복 길이 룩백)를 지정하면 앞의 패턴이 일치하지만 결과에 일치가 포함되지 않습니다.고정 길이 등가물은 다음과 같습니다.(?<=)
- 문양은 괄호 안에 들어갈 거예요. - 문양이 들어갈 거예요.하셔야 합니다.\K
가 다른할 수 있는 예: "다" 또는 "다").+
,*
,{2,4}
를 참조해 주세요.
(?=)
연산자는 고정 또는 가변 길이 패턴과 일치하며 이를 "앞보기"라고 합니다.일치하는 문자열도 결과에 포함되지 않습니다.
하지 않기 " "는 대소문자를 구분하지 않습니다.(?i)
연산자가 사용됩니다.그것은 그것에 따르는 패턴에 영향을 미치기 때문에 그것의 위치는 중요하다.
파일 이름에 다른 문자가 있는지 여부에 따라 regex를 조정해야 할 수 있습니다.이 경우 서브스트링이 캡처되는 동시에 문자열을 연결하는 예를 보여 줍니다.
는 불가능하다grep
적어도 일반적으로는 아니다.
하지만 당신의 패턴이 적절하다면, 당신은 아마도 그것을 사용할 수 있을 것이다.grep
파이프라인 내에서 여러 번 반복하여 먼저 알려진 형식으로 라인을 줄인 다음 원하는 비트만 추출합니다(단, 툴은 다음과 같습니다).cut
★★★★★★★★★★★★★★★★★」sed
훨씬 더 잘합니다.)
, 더 단순했다고 패턴은 다음과 같습니다.[0-9]+_([a-z]+)_
을 사용하다
echo $name | grep -Ei '[0-9]+_[a-z]+_' | grep -oEi '[a-z]+'
번째 ★★★★★★★★★★★★★★.grep
두 패턴과은 모두 됩니다.grep
은 (가진)--only-matching
지정)을 지정하면 이름의 알파벳 부분이 표시됩니다.이것은 패턴이 적합하기 때문에 기능합니다.알파 부분은 원하는 것을 꺼낼 수 있을 만큼 충분히 구체적입니다.
(아사이드: 개인적으로 사용하고 싶은 것은grep
+cut
원하는 것을 달성할 수 있습니다.echo $name | grep {pattern} | cut -d _ -f 2
은 「 「 」가 됩니다...cut
_
는 필드 2만을 반환합니다(필드 번호는 1부터 시작).
Unix 은 한 가지 작업을 수행하는 에 Unix는 그렇게 하지 않는다고 그래서 저는 이렇게 생각합니다.grep
+sed
etc etc 는 Unix ::::-)
이에 대한 답변은 이미 받아들여진 것은 알고 있습니다만, 엄밀히 말하면 「순수주의」의 관점에서 보면, 이 일에 적합한 툴은, 아직 언급되어 있지 않은 것 같습니다.회선을 변경해 보겠습니다.
echo $f | grep -oEi '[0-9]+_([a-z]+)_[0-9a-z]*'
name=$?
다음과 같습니다.
name=$(echo $f | pcregrep -o1 -Ei '[0-9]+_([a-z]+)_[0-9a-z]*')
캡처 그룹 1의 내용만 가져옵니다.
이 도구는 에서 이미 사용한 것과 동일한 구문을 모두 사용하지만 필요한 기능을 구현합니다.
파라미터는 다음과 같이 동작합니다.grep
인 경우)은.pcregrep
표시할 캡처 그룹을 나타냅니다.
이 솔루션에서는 스크립트에 필요한 최소한의 변경만 가능합니다.모듈러 유틸리티를 다른 유틸리티로 교체하고 파라미터를 조정하기만 하면 됩니다.
대상 주의:여러 -o 인수를 사용하여 여러 캡처 그룹을 줄에 표시된 순서대로 반환할 수 있습니다.
나는 단지 GREP로는 불가능하다고 생각한다.
sed의 경우:
name=`echo $f | sed -E 's/([0-9]+_([a-z]+)_[0-9a-z]*)|.*/\2/'`
보너스를 한번 시도해 보겠습니다.
echo "$name.jpg"
str="1w 2d 1h"
regex="([0-9])w ([0-9])d ([0-9])h"
if [[ $str =~ $regex ]]
then
week="${BASH_REMATCH[1]}"
day="${BASH_REMATCH[2]}"
hour="${BASH_REMATCH[3]}"
echo $week --- $day ---- $hour
fi
출력: 1 --- 2 --- 1
이것은 gawk를 사용하는 해결책입니다.자주 사용해야 할 것 같아서 기능을 만들었습니다.
function regex1 { gawk 'match($0,/'$1'/, ary) {print ary['${2:-'1'}']}'; }
하기만 하면
$ echo 'hello world' | regex1 'hello\s(.*)'
world
매개 변수 확장을 사용하여 마지막 밑줄에서 이름의 일부를 제거할 수 있습니다. 시작 부분에서도 마찬가지입니다.
f=001_abc_0za.jpg
work=${f%_*}
name=${work#*_}
★★★★★★★★★★★★★★★.name
가 abc
.
Apple 개발자 문서를 참조하여 '파라미터 확장'을 검색하십시오.
는 한 줄짜리 한 요.python
★★★★★★★★★★★★★★★★★」perl
다 메이저 되어 있는 가 많음), Linux unsistribution에 포함되어 있습니다.
echo $'
<a href="http://stackoverflow.com">
</a>
<a href="http://google.com">
</a>
' | python -c $'
import re
import sys
for i in sys.stdin:
g=re.match(r\'.*href="(.*)"\',i);
if g is not None:
print g.group(1)
'
및 파일 처리:
ls *.txt | python -c $'
import sys
import re
for i in sys.stdin:
i=i.strip()
f=open(i,"r")
for j in f:
g=re.match(r\'.*href="(.*)"\',j);
if g is not None:
print g.group(1)
f.close()
'
다음으로 regex 캡처 그룹을 사용하여 파일 이름에서3 문자 시퀀스를 추출하는 예를 나타냅니다.
for f in 123_abc_123.jpg 123_xyz_432.jpg
do
echo "f: " $f
name=$( perl -ne 'if (/[0-9]+_([a-z]+)_[0-9a-z]*/) { print $1 . "\n" }' <<< $f )
echo "name: " $name
done
출력:
f: 123_abc_123.jpg
name: abc
f: 123_xyz_432.jpg
name: xyz
if-regex perl
는 모든 합니다. 그룹은 에서 할 수 이로 액세스 할 수 있습니다.$1
,$2
각, 각, 각, 같, 같
bash가 있으면 확장글로빙을 사용할 수 있습니다.
shopt -s extglob
shopt -s nullglob
shopt -s nocaseglob
for file in +([0-9])_+([a-z])_+([a-z0-9]).jpg
do
IFS="_"
set -- $file
echo "This is your captured output : $2"
done
또는
ls +([0-9])_+([a-z])_+([a-z0-9]).jpg | while read file
do
IFS="_"
set -- $file
echo "This is your captured output : $2"
done
언급URL : https://stackoverflow.com/questions/1891797/capturing-groups-from-a-grep-regex
'source' 카테고리의 다른 글
새 탭 추가 버튼(+)이 있는 TabControl (0) | 2023.04.14 |
---|---|
프로세스 ID를 취득하여 nohup 프로세스를 종료하려면 어떻게 해야 합니까? (0) | 2023.04.14 |
Swift에서 iOS에 UUID 생성 (0) | 2023.04.09 |
SQL Server가 서명되지 않은 데이터 유형을 지원하지 않는 이유는 무엇입니까? (0) | 2023.04.09 |
SQL 함수를 기본 매개 변수 값으로 지정하시겠습니까? (0) | 2023.04.09 |