変数の最初の文字から最後の文字までの操作(bash)

変数の最初の文字から最後の文字までの操作(bash)

私のbashスクリプトが変数の最初の文字を処理し、最後の文字に達するまで作業を続けたいと思います。これが私が今まで持っているものです:

#!/bin/bash

echo Word?
read -r -p '' foo
# $foo is set to 'Antarctica' by user.

wordlength=${#foo}
$wordlength says 10, so start on character 1.
'A' is first letter received in $foo, so echo '{a,A}'
'n' is second letter received in $foo, so echo '{n,N}'
't' is third letter received in $foo, so echo '{t,T}'
'a' is fourth letter received in $foo, so echo '{a,A}'
........
'i' is eighth letter received in $foo, so echo '{i,I}'
'c' is ninth letter received in $foo, so echo '{c,C}'
'a' is tenth letter received in $foo, so echo '{a,A}'

ユーザー側の様子は次のとおりです。

Word?

南極大陸

{a,A}{n,N}{t,T}{a,A}{r,R}{c,C}{t,T}{i,I}{c,C}{a,A}

これがすぐに出力される内容です。これを行う方法を知っている人はいますか?


編集:このように接続できますか? $wordlengthは10なので、1から始めて10まで行きます。

if 1st letter of $foo is A, echo '{a,A}'
if 2st letter of $foo is n, echo '{n,N}'
.....

ベストアンサー1

ksh93bashまたは、文字列の各文字を繰り返すには、次のようにしますzsh

string=whatever
for ((i = 0; i < ${#string}; i++)); do
   printf '%s\n' "Character $((i + 1)): ${string: i:1}"
done

zsh(構文がサポートされてyashいないことを除いて同じ)、以下も参照してください。yashfor ((...))

for ((i = 1; i <= ${#string}; i++)); do
   printf '%s\n' "Character $i: $string[i]"
done

sまたは(分割用に)使用パラメータ拡張フラグ空の文字列を区切り文字として使用します。

for c (${(s"")string}) something with "$c"

case文字を文字列にマッピングするには、次の構文を使用できます。

case $c in
  (A) s='{O.O}';;
  (a) s='{q-p}';;
  ...
esac

または関連配列:

  • zsh:

    typeset -A map
    map=(
      A  '{O.O}'
      a  '{q-p}'
      ...
    )
    s=$map[$c]
    
  • ksh93/ bash:

    typeset -A map
    map=(
      [A]='{O.O}'
      [a]='{q-p}'
      ...
    )
    s=${map[$c]}
    

移植可能(標準sh構文を使用)次のこともできます。

map='|A={O.O}|a={q-p}|...'
s=${map#*"|$c="}
s=${s%%"|"*}

(すべての文字列に|文字がないと仮定)。

あるいは、適切なテキスト処理ユーティリティを呼び出すこともできます(コマンドを呼び出すにはシェルを使用し、テキスト処理ユーティリティを使用してテキストを処理する必要があります)。

STRING=whatever awk -F= '{map[$1] = $2}
   END {
     s = ENVIRON["STRING"]
     l = length(s)
     for (i = 1; i <= l; i++) {
       c = substr(s, i, 1)
       print map[c]
     }
   }' << EOF
A={O.O}
a={q-p}
...
EOF

(しかし、awklikeのいくつかの実装はmawkシングルバイト文字のみをサポートしています。)

おすすめ記事