sed も awk もありません。すべて bash の内部構造です。
単語は常に空白 (スペースおよび/またはタブ) で区切られていると
仮定し、単語が引数として与えられると仮定し、bash のみを記述します。
#!/bin/bash
blank=$'[ \t]'
varname='A'
n=1
while IFS='' read -r -d '' -N 1 c ; do
if [[ $c =~ $blank ]]; then n=$((n+1)); continue; fi
eval ${varname}${n}'+=("'"$c"'")'
done <<<"$@"
last=$(eval echo \${#${varname}${n}[@]}) ### Find last character index.
unset "${varname}${n}[$last-1]" ### Remove last (trailing) newline.
for ((j=1;j<=$n;j++)); do
k="A$j[@]"
printf '<%s> ' "${!k}"; echo
done
これにより、各配列 A1、A2、A3 などが設定されます ... 各単語の文字に。
の最初のループの最後の値は、$n
処理された単語の数です。印刷は少し難しいかもしれません。そのため、各文字にアクセスするためのコードが上に示されています。
サンプル テキストに適用:
$ script.sh AB DC
<A> <B>
<D> <C>
スクリプトは 2 つの (配列) varsA1
と を設定してA2
います。
そして、各文字は 1 つの配列要素です: A1[0] = A、A1[1] = B、および A2[0]=C、A2[1]=D。
$k
アクセスする配列要素に変数( )を設定する必要があります。
たとえば、echo
2 番目の単語 (1 ベース) の 4 文字目 (0 ベース) に対しては、次のことを行う必要があります (必要に応じて変更される可能性があります)。
k="A2[3]"; echo "${!k}" ### Indirect addressing.
スクリプトは次のように機能します。
$ script.sh ABCD efghi
<A> <B> <C> <D>
<e> <f> <g> <h> <i>
注意:引用しても文字が分割されます。ただし、引用符で囲まれた引数は、このスクリプトを使用してシェルのメタ文字 ( |,&,;,(,),<,>,space,tab ) の影響を回避する正しい方法です。もちろん、スペースは (たとえ繰り返されたとしても) 変数で定義されたように単語を分割します$blank
:
$ script.sh $'qwer;rttt fgf\ngfg'
<q> <w> <e> <r> <;> <r> <t> <t> <t>
<>
<>
<>
<f> <g> <f> <
> <g> <f> <g>
スクリプトは埋め込み改行を受け入れて正しく処理するため、使用する必要があるunset "${varname}${n}[$last-1]"
のは、最後の末尾の「改行」を削除することです。それが望ましくない場合は、その行を引用してください。
セキュリティに関する注意: eval は一度に1文字しか処理しないため、ここではあまり問題になりません。一人のキャラクターだけで攻撃を作るのは難しいでしょう。とにかく、通常の警告は有効です: このスクリプトを使用する前に、常に入力をサニタイズしてください。また、bash のほとんどの (引用されていない) メタ文字は、このスクリプトを壊します。
$ script.sh qwer(rttt fgfgfg
bash: syntax error near unexpected token `('