我需要编写一个脚本将电话号码从 123-123-1234 转换为 (123) 123-1234 和 1231231234。我可以使用 tr 命令更改连字符的所有实例,但如何仅更改两个中的一个?我用这段代码做了第二部分
echo "Enter phone number (xxx-xxx-xxxx)"
read phone
echo $phone | cat > phone
tr -d "-" < phone
我知道有更好的方法,但我是新学生,还不知道,提前感谢您的帮助
答案1
标题(“当字符串中存在多个字符时,如何更改该字符?”)是您尝试的解决方案,但实际问题在问题正文中进行了解释。比较XY问题。我的回答针对的是身体。
IFS=- read n1 n2 n3
这将使用用户输入的片段填充n1
,n2
和变量;n3
分别:
- 在第一个之前
-
, - 在第一个
-
和第二个之间-
, - 在第二个之后
-
(包括剩余的-
字符,如果有的话)。
然后你可以用printf
你想要的任何格式打印它们,例如
printf '(%s) %s-%s\n' "$n1" "$n2" "$n3"
printf '%s%s%s\n' "$n1" "$n2" "$n3"
你可能想要对你所接受的事物持自由态度并且不需要严格的格式。 shell 函数的示例:
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
和$n3
with printf
(如上)或以任何您想要的方式。
答案2
GNUsed
允许指定应替换(一行中)出现的模式:
第一个(默认)
echo AAAAA | sed 's/A/X/'
XAAAA
全部
echo AAAAA | sed 's/A/X/g'
XXXXX
第 i 个
echo AAAAA | sed 's/A/X/3'
AAXAA
要使用此方法专门针对您的问题,您需要进行两项修改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 之间的数字,\+
表示前一组出现一次或多次(GNU 扩展为sed
),\(<pattern>\)
并将保存模式并为其指定索引号(第一个从 1 开始,依此类推)。因此\([0-9]\+\)-
将匹配一个或多个数字,后跟破折号,并记住数字部分。
在输出中\1
打印匹配中第一个保存的模式(即[0-9]\+
......破折号之前的一个或多个数字。然后我们只需使用三个保存的数字组并根据需要格式化它们。
答案3
您意识到您正在创建一个名为phone
对吗?而且管道进入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}"
Read 可以提示用户输入,这样我们就可以消除echo
/read
组合。
然后我们使用参数扩展拉出电话号码的三个部分,并以您需要的两种格式打印它们。
注意:这不会进行任何类型的健全性检查,因此用户可以提供虚假输入,并且他们将获得虚假输出。