文字列に複数の文字がある場合、その文字のみを変更する方法はありますか?

文字列に複数の文字がある場合、その文字のみを変更する方法はありますか?

電話番号を123-123-1234から(123)123-1234および1231231234に変換するスクリプトを作成する必要があります。 trコマンドを使用してハイフンのすべてのインスタンスを変更できますが、どちらか一方を変更するにはどうすればよいですか?このコードで2番目の部分を実行しました。

echo "Enter phone number (xxx-xxx-xxxx)"
read phone
echo $phone | cat > phone
tr -d "-" < phone

より良い方法があることを知っていますが、私は新入生であり、まだそれを知りません。助けてくれてありがとう。

答え1

タイトル(「複数の文字があるときに文字列の文字を変更する方法」)は試したソリューションですが、実際の問題は質問の本文に記載されています。比較するXYの問題。私の答えは体についてです。


IFS=- read n1 n2 n3

これはそれぞれユーザー入力n1n2変数のフラグメントで埋められます。n3

  • 最初の前に-
  • 最初-と2番目の間-
  • 2文字目以降-(残りの-文字を含む)。

printfその後、任意の形式で印刷できます。

printf '(%s) %s-%s\n' "$n1" "$n2" "$n3"
printf '%s%s%s\n' "$n1" "$n2" "$n3"

欲しいかもしれませんあなたが受け入れるものに対して自由に行動します。そして厳格なフォーマットは必要ありません。シェル機能の例:

get_phone_number() {
   IFS= read -rp "Enter phone number (10 digits; additional dashes, spaces, whatever allowed): " p || return 1
   # remove non-digits
   p="$(tr -dc '0123456789' <<< "$p")"
   # check if there is 10 of them
   if [ "${#p}" -ne 10 ]; then
      echo "Wrong number of digits. Aborting." >&2; return 2
   else
      n1="${p:0:3}"
      n2="${p:3:3}"
      n3="${p:6:4}"
   fi
}

を呼び出しますget_phone_number。関数が成功したら、上記のように、または目的の方法でおよびを$n1使用します。$n2$n3printf

答え2

GNUでは、sed置き換える必要があるパターンの発生を1行に指定できます。

最初(デフォルト)

echo AAAAA | sed 's/A/X/'
XAAAA

みんな

echo AAAAA | sed 's/A/X/g'
XXXXX

i番目

echo AAAAA | sed 's/A/X/3'
AAXAA

問題に対してこの方法を使用するには、2つの修正が必要ですsed。 1)行の先頭(^)を変更して開き括弧を追加し、2)最初のダッシュを閉じ括弧と空白に置き換えます。

echo 123-123-1234 | sed 's/^/(/;s/-/) /'
(123) 123-1234

または、sed一致するパターンを許可し、パターンを括弧で囲んで(発生回数に基づいて)保存します。出力文字列から数字で呼び出すことができます。

echo 123-123-1234 | sed 's/\([0-9]\+\)-\([0-9]\+\)-\([0-9]\+\)/(\1) \2-\3/'
(123) 123-1234

これは[0-9]0から9の数字と一致します。\+つまり、前のグループが1回以上発生し(GNU拡張子はsed\(<pattern>\)パターンが保存され、インデックス番号が付与されます(最初のグループは1で始まるなど)。したがって、\([0-9]\+\)-1つ以上の数字が一致し、その後にダッシュが表示され、数字の部分が記憶されます。

\1一致する最初の保存パターン([0-9]\+ダッシュの前の数字など)を出力に印刷します。次に、保存された3つの数値グループを使用し、必要に応じてフォーマットします。

答え3

phoneRightというファイルを作成していることをご存知ですか?そしてパイピングをする必要echoはありませんcat。できますが、そうしてはいけません。echo "$phone" > phone


私はあなたのために次の解決策を思い出しました。最短の方法ではないかもしれませんが、次のように動作します。

#!/bin/bash

read -rp "Enter phone number (xxx-xxx-xxxx): " p

area_code=${p:0:3}
prefix=${p:4:3}
line=${p:8:4}

printf '%s\n%s\n' \
"($area_code) ${prefix}-${line}" \
"${area_code}${prefix}${line}"

読み取りは、ユーザーに入力を要求することによって削除echo/read結合することができます。
それから私たちはパラメータ拡張電話番号の3つの部分を取り出し、必要な2つの形式で印刷します。

注:これはいかなる種類の健全性チェックも実行しないため、ユーザーは誤った入力を提供し、誤った出力を取得します。

関連情報