![Korn Shell의 각 요소에 정규식을 적용하여 문자열 배열을 반복합니다.](https://linux55.com/image/163455/Korn%20Shell%EC%9D%98%20%EA%B0%81%20%EC%9A%94%EC%86%8C%EC%97%90%20%EC%A0%95%EA%B7%9C%EC%8B%9D%EC%9D%84%20%EC%A0%81%EC%9A%A9%ED%95%98%EC%97%AC%20%EB%AC%B8%EC%9E%90%EC%97%B4%20%EB%B0%B0%EC%97%B4%EC%9D%84%20%EB%B0%98%EB%B3%B5%ED%95%A9%EB%8B%88%EB%8B%A4..png)
names
이름과 일부 후속 정크 데이터가 포함된 문자열 배열이 있습니다 . 이와 같이
Jill Shortz, City Contractor, America
Bill Torts, Family Doctor, Canada
Will Courtz, Folk DJ, Bulgaria
Phil-Lip Warts, Juggler, India
names
정규식을 사용하여 처음 두 단어만 추출 (^\w+-*( *\w+)*)
하고 다시 작성하여 names
다음을 포함하도록 반복하고 싶습니다.
Jill Shortz
Bill Torts
Will Courtz
Phil-Lip Warts
이것이 내가 시도한 것이지만 내 AIX 시스템은 -P
Perl 모드에서 실행할 때 매개변수를 좋아하지 않습니다.
for((i=0;i<${#names[@]};++i)); do
names[$i]=`grep -P '(^\w+-*( *\w+)*)' -o <<<"${names[i]}"`
done
답변1
나는 첫 번째 쉼표 뒤의 모든 항목을 제거하기를 원한다고 가정할 때 정규식이 이 작업에 유용하다고 생각하지 않습니다.
names=( "${names[@]%%,*}" )
printf '"%s"\n' "${names[@]}"
이렇게 하면 각 배열 요소에서 첫 번째 쉼표와 그 뒤의 모든 항목(문자 그대로 "와일드카드 패턴과 일치하는 가장 긴 접미사 ,*
")이 개별적으로 제거됩니다. 그런 다음 수정된 이름의 결과 목록이 배열에 다시 할당되고 names
인쇄 됩니다 printf
.
질문과 같은 목록으로 배열을 초기화한다는 점을 고려하면 이 코드는 다음을 생성합니다.
"Jill Shortz"
"Bill Torts"
"Will Courtz"
"Phil-Lip Warts"
(큰따옴표는 printf
형식 문자열에 의해 추가됩니다).
이 코드는 , ksh93
및 에서 작동합니다 .bash
zsh
yash
답변2
ksh 매뉴얼 페이지 어디에도 문자열을 정규식과 일치시키고 캡처 괄호를 사용하여 하위 문자열을 추출할 수 있는 곳이 없습니다(bash에서와 같이
[[ $str =~ ^([[:alnum:]]+([ -]+[[:alnum:]]+)+) ]] && echo "${BASH_REMATCH[1]}"
그러나 glob 패턴에서 확장 정규식을 사용할 수 있으므로 ~(E:regex)
다음을 수행할 수 있습니다.
for n in "${names[@]}"; do
# remove the pattern from the start of the string
tmp=${n##~(E:\w+([ -]+\w+)*)}
# and then remove what remained from the end of the string
echo "[${n%$tmp}]"
done
[Jill Shortz]
[Bill Torts]
[Will Courtz]
[Phil-Lip Warts]
...그리고 최대 쓰기 전용 읽기 불가능성
for n in "${names[@]}"; do
echo "${n%${n##~(E:\w+([ -]+\w+)*)}}"
done