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의 정규식 일치 연산자를 사용합니다. 일치 결과는이라는 배열에 저장됩니다 $BASH_REMATCH
. 첫 번째 캡처 그룹은 인덱스 1에 저장되고 두 번째 (있는 경우) 인덱스 2에 저장됩니다. 인덱스 0은 전체 일치입니다.
앵커가 없으면이 정규 표현식 (및을 사용하는 정규 표현식 grep
)은 다음 예제 중 하나 이상과 일치하므로 원하는 것이 아닐 수도 있습니다.
123_abc_d4e5
xyz123_abc_d4e5
123_abc_d4e5.xyz
xyz123_abc_d4e5.xyz
두 번째와 네 번째 예를 제거하려면 정규식을 다음과 같이 만드십시오.
^[0-9]+_([a-z]+)_[0-9a-z]*
문자열은 하나 이상의 숫자로 시작 해야합니다 . 캐럿은 문자열의 시작을 나타냅니다. 정규식 끝에 달러 기호를 추가하면 다음과 같이됩니다.
^[0-9]+_([a-z]+)_[0-9a-z]*$
점이 정규식의 문자에 포함되지 않고 달러 기호가 문자열의 끝을 나타 내기 때문에 세 번째 예제도 제거됩니다. 네 번째 예제도이 일치에 실패합니다.
GNU를 가지고 있다면 grep
(약 2.5 이상이면 \K
연산자가 추가 된 것 같습니다.)
name=$(echo "$f" | grep -Po '(?i)[0-9]+_\K[a-z]+(?=_[0-9a-z]*)').jpg
\K
연산자 (가변 길이 모양 숨김)는 경기에 선행하는 패턴을 야기하지만, 결과에서 경기를 포함하지 않습니다. 고정 길이는 (?<=)
-괄호 앞에 패턴이 포함됩니다. 당신은 사용해야합니다 \K
한정사가 서로 다른 길이의 문자열을 일치 할 수있는 경우 (예를 들어 +
, *
, {2,4}
).
이 (?=)
연산자는 고정 길이 또는 가변 길이 패턴과 일치하며 "look-ahead"라고합니다. 또한 결과에 일치하는 문자열이 포함되지 않습니다.
대소 문자를 구분하지 않고 일치시키기 위해 (?i)
연산자가 사용됩니다. 그것은 패턴을 따라가므로 위치가 중요합니다.
파일 이름에 다른 문자가 있는지 여부에 따라 정규식을 조정해야 할 수도 있습니다. 이 경우 하위 문자열을 캡처하는 동시에 문자열을 연결하는 예를 보여줍니다.