![쉘 매개변수 확장 시 패턴 일치 유지](https://linux55.com/image/192714/%EC%89%98%20%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98%20%ED%99%95%EC%9E%A5%20%EC%8B%9C%20%ED%8C%A8%ED%84%B4%20%EC%9D%BC%EC%B9%98%20%EC%9C%A0%EC%A7%80.png)
${variable##pattern}
(leading) 또는 (trailing) 을 사용하여 bash 변수의 패턴을 제거할 수 있습니다 ${variable%%pattern}
.
하지만 패턴을 유지하고 나머지를 던지는 유일한 방법은 bash를 찾을 수 없습니다.
sed
, , 또는 을 사용하는 awk
솔루션이 있다는 것을 알고 있지만 grep
, 제가 간과하고 있는 합리적으로 효율적인 bash 전용 솔루션이 있는지 궁금합니다.
추신: 이것은 단지 지루한 질문이 아닙니다. 원래 문제는 이름에 패턴(기술적으로는 '[A-Z]+([A-Z])-[0-9][0-9]+([0-9])'
대시와 숫자가 뒤따르는 :대문자)이 포함된 파일을 처리하고 동일한 패턴을 사용하여 파일을 나열하고 추가 처리를 위해 일치하는 문자열을 추출하고 싶다는 것입니다. .
답변1
${var%"${var##pattern}"}
${var#"${var%%pattern}"}
예:
$ k='ab*10cd20ef*'
$ echo "${k%"${k##*[0-9]}"}"
ab*10cd20
$ echo "${k#"${k%%[0-9]*}"}"
10cd20ef*
셸이 확장을 패턴으로 해석하는 것을 방지하려면 따옴표가 중요합니다. echo "${k#${k%%[0-9]*}}"
출력되는 결과가 올바른지 확인해 보세요 .
답변2
Bash에서는 정규식을 사용할 수도 있습니다.
#!/bin/bash
re='[A-Z][A-Z]+-[0-9][0-9][0-9]+'
file=foo-BAR-1234.txt
if [[ $file =~ $re ]]; then
echo "filename '$file' matches, matching part is '${BASH_REMATCH[0]}'"
fi
를 사용하면 file=foo-BAR-1234.txt
부품이 일치 BAR-1234
하고 그에 따라 인쇄됩니다. 정규 표현식에서 괄호를 사용하여 패턴의 일부를 캡처할 수도 있으며, ${BASH_REMATCH[1]}
기타 등등에서 사용할 수 있습니다.
물론 정규 표현식의 형식은 Bash/Ksh 확장 glob의 형식과 다릅니다. 별표가 하나의 괄호 그룹에만 적용될 때 선택 사항인 괄호 대신 , 또는 가 +([abc])
필요합니다 . 및 에도 마찬가지입니다 . 또한 예를 들어 세 자리 이상을 쓸 수 있습니다 .[abc]+
([abc])+
*
?
[0-9]{3,}