Shell 编程快速入门 之 字符串

目录

[字符串 String](#字符串 String)

字符串定义

单引号字符串

双引号字符串

反引号字符串

字符串拼接

字符串长度

字符串比较

==与-eq的区别

子字符串

字符串切片

"切片步长"

遍历字符串

翻转字符串

用反向遍历来实现

调用外部命令rev实现

替换与删除字符

替换字符

删除字符

调用外部命令sed实现

删除空格

遍历字符串数组

c风格for循环

for...in循环

while循环


字符串 String

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

字符串定义

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

单引号字符串

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

bash 复制代码
#!/bin/bash
str='abcd'
echo '$str'
DATE=$(date)
echo '$DATE'

输出:

$str

$DATE

双引号字符串

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

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

输出:

abcd

Thu 24 Aug 2023 12:24:27 AM UTC

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

bash 复制代码
#!/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左边的键)字符串用于执行命令并将其输出作为字符串。例如:

bash 复制代码
#!/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. 使用字符串拼接运算符: +=

bash 复制代码
#!/bin/bash  

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

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

输出:

Hello,world!

Hello

Helloworld!

字符串长度

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

bash 复制代码
#!/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环境下单、双引号字符串在转义解析方面无区别。

字符串比较

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

bash 复制代码
#!/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比较会报错的。

bash 复制代码
#!/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"\*] 可以判断后者是否为前者的子字符串。

示例:

bash 复制代码
#!/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:正数为切片长度,即留下的字符个数;如为负数表示切掉字符串尾部的字符数

bash 复制代码
#!/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的概念,但可以用循环实现,如输出字串奇偶位数的"切片":

bash 复制代码
#!/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} 循环读取所有字符,例如:

bash 复制代码
#!/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

翻转字符串

用反向遍历来实现

bash 复制代码
#!/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实现

bash 复制代码
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}

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

输出:

hello,world

hello,shell

删除字符

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

bash 复制代码
#!/bin/bash
str="hello,world"
echo $str
echo ${str//world/}

输出:

hello,world

hello,

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

bash 复制代码
#!/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 命令来实现替换或删除:

bash 复制代码
#!/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,

删除空格

bash 复制代码
#!/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)。

示例:

bash 复制代码
#!/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循环

bash 复制代码
#!/bin/bash
array=("apple" "banana" "cherry")  

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

输出:

apple

banana

cherry

for...in循环

bash 复制代码
#!/bin/bash
array=("apple" "banana" "cherry")  

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

输出:

apple

banana

cherry

while循环

bash 复制代码
#!/bin/bash
array=("apple" "banana" "cherry")  

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

输出:

apple

banana

cherry

此时数组为空【】


相关推荐
FoldWinCard5 小时前
D5 Linux 网络及端口命令
linux·运维·服务器
零涂毕业设计6 小时前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
tedcloud1237 小时前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
霸道流氓气质7 小时前
KMS 密钥管理服务(Key Management Service)原理与实践
linux·服务器·数据库
SakitamaX7 小时前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs
小张同学a.7 小时前
Linux系统管理
linux·运维
阿龙的工作记录8 小时前
深入理解Linux设备驱动模型
linux·嵌入式硬件·工作记录
代码村新手8 小时前
Linux的基本指令
linux·运维·服务器
hkj88088 小时前
Ubuntu 切换java版本
java·linux·ubuntu
撩得Android一次心动10 小时前
Linux编程笔记3【个人用】
linux·笔记