假设我有这个清单:
39dd809b7a36
d83f42ab46a9
9664e29ac67c
66cf165f7e32
51b9394bc3f0
我想将第一次出现的字母转换为大写,例如
39dd809b7a36 - > 39Dd809b7a36
bash / awk / sed解决方案应该没问题。
感谢您的帮助。
答案 0 :(得分:3)
GNU sed可以做到
printf "%s\n" 39dd809b7a36 d83f42ab46a9 9664e29ac67c 66cf165f7e32 51b9394bc3f0 |
sed 's/[[:alpha:]]/\U&/'
给出
39Dd809b7a36
D83f42ab46a9
9664E29ac67c
66Cf165f7e32
51B9394bc3f0
答案 1 :(得分:1)
Pure Bash 4.0+使用参数替换:
string=( "39dd809b7a36" "d83f42ab46a9"
"9664e29ac67c" "66cf165f7e32" "51b9394bc3f0" )
for str in ${string[@]}; do
# get the leading digits by removing everything
# starting from the first letter:
head="${str%%[a-z]*}"
# and the rest of the string starting with the first letter
tail="${str:${#head}}"
# compose result : head + tail with 1. letter to upper case
result="$head${tail^}"
echo -e "$str\n$result\n"
done
结果:
39dd809b7a36
39Dd809b7a36
d83f42ab46a9
D83f42ab46a9
9664e29ac67c
9664E29ac67c
66cf165f7e32
66Cf165f7e32
51b9394bc3f0
51B9394bc3f0
答案 2 :(得分:0)
我想不出用基本的SW工具做任何聪明的方法,但BFI解决方案太坏了。
在One True awk(1)或gawk中:
{ n = split($0, a, "")
for(i = 1; i <= n; ++i) {
s = a[i]
t = toupper(s)
if (s != t) {
a[i] = t
break
}
}
r = ""
for(i = 1; i <= n; ++i) {
r = r a[i]
}
print r
}
Ruby中的情况并不算太糟糕:
ruby -p -e '$_ = $_.split(/(?=[a-z])/, 2); $_[1].capitalize!'
答案 3 :(得分:0)
这是我的解决方案。它不允许使用###。###形式的模式,但可以根据需要进行调整。
A = $(猫); B = $(echo $ A | sed's /([az])/ ### \ 1 ### /'| sed's /。 ###(。)###。 / \ 1 /'| sed'y / abcdefghijklmnopqrstuvwxyz / ABCDEFGHIJKLMNOPQRSTUVWXYZ /'); C =“echo $ A | sed's / [a-z] / $ B /'”; eval $ C