Shell 编程快速入门 之 字符串

8c24851c4f9c4f6dbe0de1a3181800f5.png

目录

字符串 String

字符串定义

单引号字符串

双引号字符串

反引号字符串

字符串拼接

字符串长度

字符串比较

==与-eq的区别

子字符串

字符串切片

“切片步长”

遍历字符串

翻转字符串

用反向遍历来实现

调用外部命令rev实现

替换与删除字符

替换字符

删除字符

调用外部命令sed实现

删除空格

遍历字符串数组

c风格for循环

for...in循环

while循环


字符串 String

在计算机编程中,字符串(String)是一种基本的数据类型,它表示文本或字符序列。在各种编程语言中,字符串都扮演着重要的角色,而在shell脚本中也不例外。在Shell脚本中,字符串的使用非常广泛,可以用于处理文本、文件名、命令参数等等。

字符串定义

在shell中,字符串可以用单引号、双引号或反引号来定义。

单引号字符串

单引号字符串中的内容将原样输出,不会进行任何变量替换。例如:

#!/bin/bash
str='abcd'
echo '$str'
DATE=$(date)
echo '$DATE'

输出:

$str
$DATE

双引号字符串

双引号字符串中的内容将进行变量替换。例如:

#!/bin/bash
str='abcd'
echo "$str"
DATE=$(date)
echo "$DATE"

输出:

abcd
Thu 24 Aug 2023 12:24:27 AM UTC

【注意】据说有的shell环境两者还区别于它们转义字符的解析,但至少我用的版本没有差别:

#!/bin/bash
echo 'Hello\n World!'
echo "Hello\n World!"

echo -e 'Hello\n World!'
echo -e "Hello\n World!"

输出:

Hello\n World!
Hello\n World!
Hello
 World!
Hello
 World!

反引号字符串

反引号(``,数字1左边的键)字符串用于执行命令并将其输出作为字符串。例如:

#!/bin/bash  
  
# 获取当前日期并存储到变量中  
current_date=`date`  
echo "当前日期是:$current_date"

result=`ls -l | wc`  
echo "命令序列的输出是:$result"

输出:

当前日期是:Thu 24 Aug 2023 10:28:54 AM UTC
命令序列的输出是:      3      20     118

字符串拼接

1. 字符串自然的首尾相接在一起
2. 使用字符串拼接运算符: +=

#!/bin/bash  

str1="Hello"
str2="world!"
str3="${str1},${str2}"
echo $str3

str+=$str1
echo $str
str+=$str2
echo $str

输出:

Hello,world!
Hello
Helloworld!

字符串长度

要获取字符串的长度,可以使用${#string}。例如:

#!/bin/bash  
  
str='Hello\nWorld'
echo "$str的长度为:"${#str}

str="Hello\nWorld"
echo "$str的长度为:"${#str}

current_date=`date`  
echo "date命令返回的字串长度为:${#current_date}"

输出:

Hello\nWorld的长度为:12
Hello\nWorld的长度为:12
date命令返回的字串长度为:31
 

注:同时也印证了我用的linux环境下单、双引号字符串在转义解析方面无区别。

字符串比较

字符串没有大小之分,只能比较是否相等 == 、不相等 !=。

#!/bin/bash
str1='Hello'  
str2='World'  
if [ "$str1" == "$str2" ]; then  
    echo "Strings are equal"  
else  
    echo "Strings are not equal"  
fi

输出:

Strings are not equal

==与-eq的区别

字符串对比通常用 ==,可转数字的字符串也能用 -eq,但不能转数字的用-eq比较会报错的。

#!/bin/bash
num1="123"
num2="0123"

if [ "$num1" -eq "$num2" ]; then  
    echo "Numbers are equal"  
else  
    echo "Numbers are not equal"  
fi

if [ "$num1" == "$num2" ]; then  
    echo "Numbers are equal"  
else  
    echo "Numbers are not equal"  
fi

输出:

Numbers are equal
Numbers are not equal

子字符串

字符串的比较支持通配符 “?”"*",分别表示可以代替一个和多个字符。

例如,[[$string == *"$substring"*]] 可以判断后者是否为前者的子字符串。

示例:

#!/bin/bash
string="Hello World"  
substring="Hello"  
if [[ $string == *"$substring"* ]]; then  
    echo "Substring found"  
else  
    echo "Substring not found"  
fi

if [[ $string == "$substring"* ]]; then  
    echo "String starts with Substring"  
elif  [[ $string == *"$substring" ]]; then  
    echo "String ends with Substring"
elif  [[ $string == *"$substring"* ]]; then  
    echo "Substring is in the middle of String"
else  
    echo "Substring not found"  
fi

输出:

Substring found
String starts with Substring

字符串切片

格式: ${string: start,length切片长度}

start:切片起始索引位置,索引从0开始。可以理解为切掉字符串前部的字符数。
length:正数为切片长度,即留下的字符个数;如为负数表示切掉字符串尾部的字符数

#!/bin/bash  
  
str="Hello,world!"
echo ${str:0:5}   # 输出 "Hello"
echo ${str::5}    # 输出 "Hello"
echo ${str:1:5}   # 输出 "ello,"
echo ${str:8:5}   # 输出 "rld!"
echo ${str::-1}    # 输出 "Hello,world"
echo ${str::-5}    # 输出 "Hello,w"
echo ${str:3:-3}   # 输出 "lo,wor"

输出:

Hello
Hello
ello,
rld!
Hello,world
Hello,w
lo,wor

“切片步长”

shell没有切片步长step的概念,但可以用循环实现,如输出字串奇偶位数的“切片”:

#!/bin/bash  
  
string="Hello,world!"
result=""
index=0
step=2
while [ $index -lt ${#string} ]; do
    char=${string:$index:1}
    index=$((index+step))
	result+=$char
done
echo $result

result=""
index=1
while [ $index -lt ${#string} ]; do  
    char=${string:$index:1}
    index=$((index+step))
	result+=$char
done
echo $result

result=""
for ((i=1; i<${#string}; i=i+step)); do  
    char=${string:$i:1}
	result+=$char
done
echo $result

输出:

Hlowrd
el,ol!
el,ol!

遍历字符串

使用单个字符的切片 ${str:$i:1} 循环读取所有字符,例如:

#!/bin/bash
str="hello,world"

echo $str
for (( i=0; i<${#str}; i++ )); do
    echo -n ${str:$i:1}" "
done

输出:

hello,world
h e l l o , w o r l d  

翻转字符串

用反向遍历来实现

#!/bin/bash
str="hello,world"

echo $str
# 反向遍历
for (( i=${#str}-1; i>=0; i-- )); do
    echo -n ${str:$i:1}" "
done
echo

str2=""
# 反向拼接
for (( i=${#str}-1; i>=0; i-- )); do
    str2+=${str:$i:1}
done
echo $str2

输出:

hello,world
d l r o w , o l l e h 
dlrow,olleh

调用外部命令rev实现

hann@HannYang:~$ str="hello,world"
hann@HannYang:~$ echo $str
hello,world
hann@HannYang:~$ echo $str|rev
dlrow,olleh
hann@HannYang:~$ echo $str
hello,world
hann@HannYang:~$ str=`echo $str`
hann@HannYang:~$ echo $str
hello,world
hann@HannYang:~$ str=`echo $str|rev`
hann@HannYang:~$ echo $str
dlrow,olleh

替换与删除字符

替换字符

格式:${string//pattern/replacement} 

#!/bin/bash
str="hello,world"
echo $str
echo ${str//world/shell}

输出:

hello,world
hello,shell 

删除字符

格式:${string//pattern/} 替换内容replacement为空即删除。

#!/bin/bash
str="hello,world"
echo $str
echo ${str//world/}

输出:

hello,world
hello,

【注意】替换和删除操作都不是原地操作,要改变原字符串,请操作后赋值:

#!/bin/bash
str="hello,world"
echo $str
echo ${str//world/shell}
echo ${str//world/}
echo

echo $str
str=${str//world/}
echo $str

输出: 

hello,world
hello,shell
hello,

hello,world
hello,

调用外部命令sed实现

比如,调用 sed 命令来实现替换或删除:

#!/bin/bash
str="hello,world"

new_string=$(echo $str | sed 's/world/Shell/g')
echo $new_string

#直接用反引号字符串表示:
echo `echo $str | sed 's/world//g'`

输出:

hello,Shell
hello,

删除空格

#!/bin/bash
str=" hello world 1 2 3 4 5 "
no_space_str=${str//[[:space:]]/}
echo $no_space_str

输出:

helloworld12345 

POSIX 标准定义的字符类

除了[[:space:]]表示匹配空格(包括空格、制表符、换页符等),还有以下特殊格式可用:

[[:alnum:]]:匹配字母和数字。
[[:alpha:]]:匹配字母。
[[:digit:]]:匹配数字。
[[:graph:]]:匹配可见字符(非空格和非控制字符)。
[[:lower:]]:匹配小写字母。
[[:upper:]]:匹配大写字母。
[[:punct:]]:匹配标点符号。
[[:print:]]:匹配可打印字符(非控制字符)。
[[:cntrl:]]:匹配控制字符(0x01 到 0x1F 和 0x7F)。

示例:

#!/bin/bash
str=" Hello123World 1 2 , 3 4 5"
str1=${str//[[:digit:]]/}
echo [$str1]
str2=${str//[[:upper:]]/}
echo [$str2]
str3=${str//[[:alnum:]]/}
echo [$str3]
str4=${str//[[:alpha:]]/}
echo [$str4]
str5=${str//[[:punct:]]/}
echo [$str5]

输出:

[ HelloWorld , ]
[ ello123orld 1 2 , 3 4 5]
[ , ]
[ 123 1 2 , 3 4 5]
[ Hello123World 1 2 3 4 5]

遍历字符串数组

c风格for循环

#!/bin/bash
array=("apple" "banana" "cherry")  

for ((i=0; i<${#array[@]}; i++))  
do  
    echo "${array[i]}"  
done

输出:

apple
banana
cherry

for...in循环

#!/bin/bash
array=("apple" "banana" "cherry")  

for item in "${array[@]}"  
do  
    echo "$item"  
done

输出:

apple
banana
cherry

while循环

#!/bin/bash
array=("apple" "banana" "cherry")  

while [ ${#array[@]} -gt 0 ]  
do  
    echo "${array[0]}"  
    array=("${array[@]:1}")  
done
echo "此时数组为空【${array[@]}】"

输出:

apple
banana
cherry
此时数组为空【】


猜你喜欢

转载自blog.csdn.net/boysoft2002/article/details/132462179