names
名前といくつかの後続のジャンクデータを含む文字列配列があります。このように
Jill Shortz, City Contractor, America
Bill Torts, Family Doctor, Canada
Will Courtz, Folk DJ, Bulgaria
Phil-Lip Warts, Juggler, India
names
正規表現を使用して最初の2つの単語のみを抽出して書き直し、(^\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