将替代字符从下到高,从上到低 - Unix 外壳脚本

  • 本文关键字:Unix 外壳脚本 字符 bash unix
  • 更新时间 :
  • 英文 :


如何转换传递给脚本的字符串的替代字符,如果它较低,则应将其转换为高字符,如果为高则转换为下部?

read -p " Enter string" str
for i in `seq 0 ${#str}`
do
#echo $i
rem=$(($i % 2 ))
if [ $rem -eq 0 ]
then
echo ${str:$i:1}
else
fr=${str:$i:1}
if [[ "$fr" =~ [A-Z] ]]
then
echo ${str:$i:1} | tr '[:upper:]' '[:lower:]'
elif [[ "$fr" =~ [a-z] ]]
then
echo ${str:$i:1} | tr '[:lower:]' '[:upper:]'
else
echo ""
fi
fi
done

你的问题有点挑战,因为它被标记为shell,而不是与 bash 或 zsh 等高级 shell 有关的问题。在 POSIX shell 中,您没有字符串索引,没有 C 样式的for循环,也没有使用字符类模式匹配的[[ .. ]]运算符。

但是,通过一些笨拙的创造力,旧的expr和POSIX字符串和算术运算,并将字符串限制为ASCII字符,您可以迭代字符串,将写更改为小写,写和大写,同时保持所有其他字符不变。

如果您有可用的高级 shell,我不推荐这种方法,但如果您仅限于 POSIX shell,因为您的问题被标记,它会起作用,但不要指望它会超快......

#!/bin/sh
a=${1:-"This Is My 10TH String"}    ## input and output strings
b=
i=1                                 ## counter and string length
len=$(expr length "$a")
asciiA=$(printf "%d" "'A")          ## ASCII values for A,Z,a,z
asciiZ=$(printf "%d" "'Z")
asciia=$(printf "%d" "'a")
asciiz=$(printf "%d" "'z")
echo "input : $a"       ## output original string
while [ "$i" -le "$len" ]; do       ## loop over each character
c=$(expr substr "$a" "$i" "1")  ## extract char from string
asciic=$(printf "%d" "'$c")     ## convert to ASCII value
## check if asciic is [A-Za-z]
if [ "$asciiA" -le "$asciic" -a "$asciic" -le "$asciiZ" ] ||
[ "$asciia" -le "$asciic" -a "$asciic" -le "$asciiz" ]
then    ## toggle the sign bit (bit-6)
b="${b}$(printf "x$(printf "%x" $((asciic ^ 1 << 5)))n")" 
else
b="$b$c"        ## otherwise copy as is
fi
i=$(expr $i + 1)
done
echo "output: $b"       ## output resluting string

大小写更改是通过依赖每个大写或小写字符的 ASCII 值中大小写位 (bit-6) 的简单位切换来将其从小写更改为大写,反之亦然。(请注意,您可以将printf和位移换成asciictr作为替代方案)

示例使用/输出

$ sh togglecase.sh
input : This Is My 10TH String
output: tHIS iS mY 10th sTRING

当您想每隔一个字符大小写擦拭一次时,请尝试以下操作:

read -p " Enter string " str
for i in `seq 0 ${#str}`; do
rem=$(($i % 2 ))
if [ $rem -eq 0 ]
then
printf "%s"  "${str:$i:1}"
else
fr=${str:$i:1}
printf "%s" "$(tr '[:upper:][:lower:]' '[:lower:][:upper:]' <<<  "${str:$i:1}")"
fi
done
echo

编辑:第二种解决方案 切换 str 的大小写并合并新旧字符串。

#!/bin/bash
str="part is lowercase & PART IS UPPERCASE"
str2=$(tr '[:upper:][:lower:]' '[:lower:][:upper:]' <<< "${str}")
str_chopped=$(sed -r 's/(.)./1n/g' <<< "${str}");
# Will have 1 additional char for odd length str
# str2_chopped_incorrect=$(sed -r 's/.(.)/1n/g' <<< "${str2}");
str2_chopped=$(fold -w2 <<< "${str2}" | sed -nr 's/.(.)/1/p' );
paste -d 'n' <(echo "${str_chopped}") <(echo "${str2_chopped}") | tr -d 'n'; echo

最新更新