Linux sed命令解析

sed是一种非交互式流编辑器,处理一行内容时将其存储在模式空间中。它用于自动编辑文件,简化重复操作,常见用途包括文本过滤、替换和删除。sed命令包括-n(静默模式)、-e(编辑动作)、-f(读取动作文件)、-r(使用扩展正则)和-i(直接修改文件)。常用的sed动作有p(打印)、d(删除)、s(替换)和w(写入)。sed通过正则表达式进行匹配,有贪婪性特点,且利用临时寄存器处理数据。它还能实现批量文件扩展名修改和连续字符替换等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

sed是一种流线型、非交互式编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有改变,除非使用重定向存储输出。sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
sed中动作都是使用单引号(’ ')括起来的。

选项与参数:

  • -n :使用安静(silent)模式。在一般 sed 的用法中,所有来自 STDIN 的数据一般都会被列出到终端上。但如果加上 -n 参数后,则只有经过sed 特殊处理的那一行(或者动作)才会被列出来。
  • -e :直接在命令列模式上进行 sed 的动作编辑;
  • -f :直接将 sed 的动作写在一个文件内, -f filename 则可以运行 filename 内的 sed 动作;
  • -r :sed 的动作支持的是延伸型正则表达式。(默认是基础正则表示法语法)
  • -i :直接修改读取的文件内容,而不是输出到终端,文件内容会改变。

常用命令:

  • p : 打印,将某个选择的数据打印出来。通常会与参数sed -n 一起使用
  • d : 删除,不用跟任何参数
  • s : 替换,通常这个s的动作可以搭配正规表示法。
  • w:将替换成功的行写入指定文件中

p :打印动作分析

不加参数直接使用p命令打印:

[root@admin home]# sed 'p' 12.txt
asdfsd
asdfsd
cccdgg
cccdgg
#直接使用一个p,将内容打印了2遍

[root@admin home]# sed '1p' 12.txt
asdfsd
asdfsd
cccdgg

使用1p时,只是把第一行打印了2遍
这些都是sed的特性,将所有来自 STDIN 的数据都被列出到终端上。然后又加了一个数字1,那第一行又被打印了一次。

加上-n参数后,指定哪行打印哪行:

[root@admin home]# sed -n '1p' 12.txt  
asdfsd

这样的效率是最高的,对整个文件只遍历一次

sed通常情况下会通过管道的形式来完成它的任务。

打印第2行到第4行,包括边界行:

[root@admin home]# cat -n 11.txt | sed -n '2,4p'
     2	
     3	bbbb
     4	this is aaccdd	
     

cat -n 表示列出行号,如这的 2 3 4。
这个效率要差一些,因为cat就已经将文件遍历一次,然后通过管道的形式传给sed,sed再去打印出来。
也可以使用下面的命令实现这个打印

[root@admin home]# cat -n 11.txt | head -4 | tail -3

这种效率是最低的,先通过cat遍历一遍整个文件,然后通过管道传给head,head再取出前4行,然后再通过管道传给tail,tail再打印出后3行。明显多出了几步,这个文件的行数少,到时没多大影响,但要是文件内容多了,效率就很低了。

sed中的匹配,使用 /…/ 实现

#匹配文件中连续的bb的内容,这个动作跟grep很像
[root@admin home]# cat 11.txt | sed -n '/bbb*/p'
bbbb
ccccbbbcccdddfgg

sed中加入正则表达式

#打印出文件中所有的空行,sed可以包括换行符\n,制表符\t,空格等形成的空行。
[ \t]就代表空行。
[root@admin home]# cat 11.txt | sed -n '/^[ \t]*$/p'

#打印文件中以this单词开头的行
[root@admin home]# cat 11.txt | sed -n '/^this/p'
this is aaccdd

扩展正则表达式:
[root@admin tody]# sed -r 's/ab+/!/' a.txt 
this is a test
a
aa
!
!
!c

对于扩展的正则表达式字符,比如 +、?、| ,前面必须加 -r 参数。
基础的是 . 、 * 、 ^ 、 $等。

打印文件中两个以this开头行及其之间的行

[root@admin home]# cat 11.txt | sed -n '/this/,/this/p'
this is aaccdd	
				
ccccbbbcccdddfggi

this is space
#及两次匹配this,中间用逗号隔开

但是这种匹配会引出一个问题,当我文件内容中有3个或者3个以上的行都是以this开头的,它又会怎么打印呢?实例如下:

实例1:

#匹配打印this及其之间的行
[root@admin home]# cat 11.txt
aaaaa
bbbb
this is aaccdd					
ccccbbbcccdddfggi
this is space
sdfggccdd
this this 
dsdf
[root@admin home]# cat 11.txt | sed -n '/this/,/this/p'
this is aaccdd					
ccccbbbcccdddfggi
this is space
this this 
dsdf

实例2:

#匹配打印连续字母a和连续字母b及其之间的行
[root@admin home]# cat 12.txt
asdfad
aaaaaddfd
sdfsdfghghdf
bbbbbhjjh
this is aaaa
asdfa
bbbb
gewrwe
[root@admin home]# cat 12.txt | sed '/aaa*/,/bbb*/p'
asdfad
gewrwe

实例3:

#匹配打印字母a和字母b及其之间的行
[root@admin home]# cat 14.txt
a
b
b
a
b
c
d
e
f
[root@admin home]# cat 14.txt | sed  '/a/,/b/d'
b
c
d
e
f

上面几个实例中,怎么好像有的实例的运行结果并不是我们预想的呢?为什么会出现这样的结果呢?
其实这里有三种情况,我把它浓缩成两种情况来说明一下出现这样结果的原因:

第一种情况,是命令中第一个需要匹配的字符或者是字符串在文中出现的位置,在与第二个需要匹配的字符或字符串成对匹配的过程中,位置始终在第二个需要匹配的字符或字符串位置的前面,如上面实例2中连续的a与连续的b在成对匹配,连续的a的位置始终在连续b的前面,这样的文件内容在匹配时出现上面情况的原因如下:

其实原因很简单,就是编写人设计的算法原理的问题。sed工具就是一次处理一行的内容,当找到第一次出现this的行以后,它会对这个行做个标记,比如为1。然后继续寻找第二次出现this的行,标记为2(注意:无论这行中有多少个this,都算在一行来处理),然后将这几行的内容打印出来。但是这个文件内容还没扫描完,它会继续往下扫描,继续寻找第三次出现this的行,作为第一个匹配的项,标记为3,再继续往下寻找第4次出现this的行,作为第二个匹配的项,如果找到了,再接着把这几行的内容打印出来,然后再依照这样的原理继续寻找下去,直到文件结束。但是在这期间还会有一个小插曲,就是当出现this的行不是偶数行时,那最后一次出现this的行以及下面的所有内容都会被打印出来(此时就相当于运行的是cat 11.txt | sed -n ‘/this/,//p’,这是可以匹配出this及其下面所有的内容的),这是由于sed匹配的贪婪性造成的。

第二种情况:在成对的匹配中,当第二个需要匹配的字符或字符串出现的位置先与第一个需要匹配的字符或字符串时,程序不会理会它,还是继续寻找第一个需要匹配的字符或字符串,就像上面的实例3,当第一次找到a和b后,打印出a b,然后继续开始寻找下一个a,虽然b出现在第三行,先于第二次寻找的a,但是它不理会,然后继续找下面的与能与a组队的b,如果找到就打印出来,直到文件结束。如果找到了a,但是下面没有b了,那么就会打印出a及其下面所有的内容(相当于在接下来的内容中执行了cat 14.txt | sed -n '/a/,//p’命令,这也是会打印出a下面所有的内容的);如果没找到a,那么程序结束,下面的内容不打印。

d : 删除动作分析
语法结构:

sed '/寻址/d'
  • a:追加命令,匹配行的下一行插入一行;sed ‘/寻址/a 新的内容’
  • i:插入命令,匹配行的上一行插入一行;sed ‘/寻址/i 新的内容’
  • c:更改命令,更改匹配行的内容;sed ‘/寻址/c 新的内容’

注:源文件的内容并没有被真正的删除)类时与grep的-v参数
但是加上-i参数后,就可以操作文件的内容了,而不需要打印到屏幕。

#删除第二行
[root@admin home]# cat 11.txt | sed '2d'

#删除匹配this的行
[root@admin home]# cat 11.txt | sed '/this/d'

查看一下原文件,内容并没有真正的被删除。如果想实现真正删除,有两种做法:

  • 方法一:可以通过重定向实现,就是想删除后的内容重定向到一个新的文件中,然后再用该文件去覆盖原文件,当然最好将原文件备份一下,推荐这种做法。
  • 方法二:使用sed的-i 参数。sed -i ‘/this/d’ 11.txt,但是不推荐这种做法,比较危险,有可能写错了导致删错。
[root@admin home]# cat 12.txt
asdfad
aaaaaddfd
sdfsdfghghdf
bbbbbhjjh
this is aaaa
asdfa
bbbb
aaaadddg
dgewrwe

#删除连续a和连续b之间的行
[root@admin home]# cat 12.txt | sed '/aaa*/,/bbb*/d'
asdfad

#首先分析一下,按照要求删除后结果应该是:
asdfad
this is aaaa

[root@admin home]# cat 12.txt | sed '/aaa*/,/bbb*/d'
asdfad   <--咿,这个结果好奇怪

上面运行的结果尽然不是我们想要的结果,为什么会这样的情况呢?其实这个跟上面讲的打印匹配两this及其之间的行的原理是一样的,这里就不阐述了。都是sed匹配的贪婪性造成的。

[root@admin tody]# cat a.txt 
this is a test
a
aa bb
abb
abbb
abbc

# 匹配上上一行插入
[root@admin tody]# sed '/aa/i line' a.txt 
this is a test
a
line
aa
abb
abbb
abbc

# 匹配行下一行插入
[root@admin tody]# sed '/aa/a line' a.txt 
this is a test
a
aa bb
line
abb
abbb
abbc

#更改匹配行
[root@gloryroad tody]# sed '/aa/c line' a.txt 
this is a test
a
line
abb
abbb
abbc

s : 替换动作分析

sed的替换原理是,针对每一行从左到右进行扫描,每次替换一个,并且每一次替换都会产生一个临时寄存器,等到这一次替换完成或者后续需要的命令执行完成,才销毁这个临时寄存器,进行第二次匹配时,再产生新的临时寄存器。
如:

[root@admin home]# cat 14.txt | sed 's/a/c/' 

替换命令格式:sed ‘s/a/c’,先写替换动作s,接下来写要替换的字符串,然后写替换后的字符串

有如下一个文件,其内容如下:

[root@admin home]# cat 16.txt
asdf
bsd
b
aacdf
b
c
aaffdd
d
b
b
e
f

将每行第一次出现的字母a替换成字母c

[root@admin home]# cat 16.txt | sed 's/a/c/'
csdf
bsd
b
cacdf
b
c
caffdd
d
b
b
e
f

上面的写法只能替换每行第一次出现的字母a,如果想把所有的a都替换成c的话,就需要加上一个全局参数g。但如果想替换指定那一次匹配的,可以将g改为确定的数字

[root@admin home]# cat 16.txt | sed 's/a/c/g'
csdf
bsd
b
cccdf
b
c
ccffdd
d
b
b
e
f
# 只替换第二次匹配的
[root@admin tody]# sed 's/a/A/2' b.txt 
abcdwedAsdg
aAcdfwa
adfeAaadf
a

增加模式匹配,然后替换

[root@admin home]# cat 16.txt
aasdfff
bsd
b
aacdffgg
b
c
aaffdd

将所有含有a字母的行中的字符f替换成z

[root@admin home]# cat 16.txt | sed '/a/s/f/z/g'
aasdzzz
bsd
b
aacdzzgg
b
c
aazzdd

/a/代表模式匹配,必须是//包围。但替换则不一定适用//包围,也可以使用#或者是@符号代替/,这种替换可以用到需要转义的时候。如:

[root@admin home]# cat 16.txt | sed '/a/s#f#z#g'

sed命令中使用单双引号都是可以的,但什么时候必须二选一呢?
当需要匹配的字符串中含有双引号时,外面就用单引号包围,如果里面含有单引号时,外面就用双引号包围。这样做的好处时,可以避免转义单双引号。

#将第4行的所有f替换成z
[root@admin home]# cat 16.txt | sed "4s/f/z/g"
aasdfff
bsd
b
aacdzzgg
b
c
aaffdd

#将所有的字母都换成大写的Z
[root@admin home]# echo "111sss23jjsddd89" | sed 's/[a-zA-Z]/Z/g'
111ZZZ23ZZZZZZ89

使用sed命令也可以实现删除以某个字符或者字符串,实现的方法是,将需要删除的字符或字符串替换成空。

[root@admin home]# cat 16.txt
aasdfff
bsd
b
aacdffgg
b
c
aaffdd

#将连续的a字符串删除
[root@admin home]# cat 16.txt | sed 's/aaa*//'
sdfff
bsd
b
cdffgg
b
c
ffdd

一个特例:

[root@admin home]# echo "111sss23jjsddd89" | sed 's/.*/Z/g'
Z  # 还是正则的贪婪性,.*表示所有的字符

[root@admin home]# echo "111sss23jjsddd89" | sed 's/./Z/g'
ZZZZZZZZZZZZZZZZ
[root@admin home]# echo "111sss23jjsddd89" | sed 's/[a-zA-Z]*/Z/g'
Z1Z1Z1Z2Z3Z8Z9Z

出现这样的结果是因sed特性和正则表达式的贪婪性造成的。因为*可以代表0次,所以在匹配第一个数字1时,没有匹配上,因为它不是字母,相当于匹配了0次,所有在前面加了一个字母Z,下面的数字前加了一个字母Z 的原理也是这样的。

sed的临时寄存器
临时寄存器就是用来临时存放数据用的,我们通过一道金典的关于sed的面试题讲解一下临时寄存器。sed会为每一次匹配生产一个临时寄存器,匹配以及后面的动作完成后,再销毁这个临时寄存器,为下一次匹配开辟新的临时寄存器。即每一次匹配都会产生一个新的临时寄存器。

1、批量修改文件的扩展名:将文件夹下所有的 .txt文件改成 .jpg文件

[root@admin test]# ls
aa.txt  ls.txt  result.txt  right.txt  sd.ex  wrong.txt

#将test目录中所有以.txt文件改成.jpg结尾的文件
[root@admin test]# ls | sed 's/\(.*\)txt/ mv \1txt \1jpg/' | sh
sh: line 5: sd.ex: command not found
[root@admin test]# ls
aa.jpg  ls.jpg  result.jpg  right.jpg  sd.ex  wrong.jpg

从上面的运行结果可以看出已经修改成功,那个报错我们先不管它。
解题思路分析如下:
首先,我们之前在将sed时说过,它得到的任何结果都不会改变原文件中的内容,所以我们没法直接通过替换命令(ls | sed ‘s/txt/jpg/’)去修改文件的扩展名,这样是实现不了修改原文件的扩展名的。
其次,修改文件的扩展名是通过 mv 命令实现的, 所以要想修改.txt文件为.jpg文件,所以我们必须构造出类似下面的语句

mv aa.txt aa.jpg

最后,把上面实现出的修改文件扩展名的命令语句交给 sh 命令去执行。只有执行了这样的语句,才能实现真正修改文件扩展名的功能。

sed 's/\(.*\)txt/ mv \1txt \1jpg/'命令的详细分析如下:

s : 是替换

\(\) : 这是临时寄存器的固定写法,括号需要转义,因为sed在执行过程中没有存储的功能,但我们修改的也仅是文件的扩展名,所以文件名还是需要被保留的,这个时候就需要先把文件的扩展名临时存放在临时寄存器中,用到时,直接去取出来用。
如果用到了多个临时寄存器,取时需要使用\1, \2等表示。\1表示第一个临时寄存器,\2表示第二个临时寄存器....

.* :是匹配所有的字符,就是文件名

注:sed一次只处理一行的内容,所以文件目录中有多少个.txt文件,就被划分成多少行,然后ls把.txt文件逐行地交给sed去处理。
所以通过这样的语句处理后:

[root@admin test]# ls | sed 's/\(.*\)txt/ mv \1txt \1jpg/'
 mv aa.txt aa.jpg
 mv ls.txt ls.jpg
 mv result.txt result.jpg
 mv right.txt right.jpg
 mv wrong.txt wrong.jpg

我们需要修改文件扩展名的命令就构造好了,最后就是通过管道符交给 sh 命令去执行这个修改文件扩展名的命令了,这样就达到了我们批量修改文件扩展名的功能。

2、将文件中连续出现的字符替换成一个字符,如aaaaaa替换成a

[root@admin home]# cat 17.txt 
1aaaaaaaaa2
1bbbbbbbbb323
3cccccc45
dddddd
eeeeee
asdfsdf
rrrfdgsdfffff

#将17.txt文件中连续出现的字符替换成一个相应的字符
[root@admin home]# cat 17.txt | sed 's/\(.\)\1\1*/\1/'
1a2
1b323
3c45
d
e
asdfsdf
rfdgsdfffff

解答分析:

sed 's/\(.\)\1\1*/\1/'

. :正则表达式中,点号表示匹配一个任意字符,因为这里我不知道都有哪些字符,所以使用一个点代替一个任一字符。

\(.\) :将这个任一的字符存放到临时寄存器中,后面两\1表示再取出2次这个任一字符,紧跟在它后面,相当于将匹配到的那个任一字符又复制了2次,再粘贴2次,这样就组成了3个连续的字符,如aaa,三个连续的字符再加一个星号,就表示匹配连续的字符串了。
最后面一个\1,就代表替换成一个相应的字符。

w:写入文件

[root@gloryroad tody]# cat b.txt | sed 's/a/A/w bb.txt' 
Abcdwedasdg
Aacdfwa
Adfeaaadf
A
[root@gloryroad tody]# cat bb.txt 
Abcdwedasdg
Aacdfwa
Adfeaaadf
A

寻址
sed默认对每行进行操作,增加寻址后对匹配的行进行操作。
常用寻址有:

  • /正则表达式/s/old/new/g
  • 行号s/old/new/g(行号可以是具体行号,也可以是最后一行 符 号 , 还 可 以 是 第 几 行 到 第 几 行 , 如 1 , 3 ; 1 , 符号,还可以是第几行到第几行,如1,3; 1, 1,3;1,
  • 可以两个寻址符号,也可以混合使用行号和正则地址
[root@admin tody]# cat passwd 
adm:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:adm/bin:/sbin/nologin
daemon:x:2:2:adm:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

# 通过行号寻址
[root@gloryroad tody]# head -6 passwd | sed '4s/adm/!/g'
adm:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:adm/bin:/sbin/nologin
daemon:x:2:2:adm:daemon:/sbin:/sbin/nologin
!:x:3:4:!:/var/!:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

[root@gloryroad tody]# head -6 passwd | sed '1,4s/adm/!/g'
!:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:!/bin:/sbin/nologin
daemon:x:2:2:!:daemon:/sbin:/sbin/nologin
!:x:3:4:!:/var/!:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

# 通过正则进行寻址,以daemon开头的行替换
[root@gloryroad tody]# head -6 passwd | sed '/daemon/s/adm/!/g'
adm:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:adm/bin:/sbin/nologin
daemon:x:2:2:!:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync

# 行号和正则混用,从以bin开头的行开始到最后一行进行替换
[root@gloryroad tody]# head -6 passwd | sed '/^bin/,$s/adm/!/g'
adm:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:!/bin:/sbin/nologin
daemon:x:2:2:!:daemon:/sbin:/sbin/nologin
!:x:3:4:!:/var/!:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
内容概要:本文档详细介绍了在三台CentOS 7服务器(IP地址分别为192.168.0.157、192.168.0.158和192.168.0.159)上安装和配置Hadoop、Flink及其他大数据组件(如Hive、MySQL、Sqoop、Kafka、Zookeeper、HBase、Spark、Scala)的具体步骤。首先,文档说明了环境准备,包括配置主机名映射、SSH免密登录、JDK安装等。接着,详细描述了Hadoop集群的安装配置,包括SSH免密登录、JDK配置、Hadoop环境变量设置、HDFS和YARN配置文件修改、集群启动与测试。随后,依次介绍了MySQL、Hive、Sqoop、Kafka、Zookeeper、HBase、Spark、Scala和Flink的安装配置过程,包括解压、环境变量配置、配置文件修改、服务启动等关键步骤。最后,文档提供了每个组件的基本测试方法,确保安装成功。 适合人群:具备一定Linux基础和大数据组件基础知识的运维人员、大数据开发工程师以及系统管理员。 使用场景及目标:①为大数据平台建提供详细的安装指南,确保各组件能够顺利安装和配置;②帮助技术人员快速掌握Hadoop、Flink等大数据组件的安装与配置,提升工作效率;③适用于企业级大数据平台的建与维护,确保集群稳定运行。 其他说明:本文档不仅提供了详细的安装步骤,还涵盖了常见的配置项解释和故障排查建议。建议读者在安装过程中仔细阅读每一步骤,并根据实际情况调整配置参数。此外,文档中的命令和配置文件路径均为示例,实际操作时需根据具体环境进行适当修改。
在无线通信领域,天线阵列设计对于信号传播方向和覆盖范围的优化至关重要。本题要求设计一个广播电台的天线布局,形成特定的水平面波瓣图,即在东北方向实现最大辐射强度,在正东到正北的90°范围内辐射衰减最小且无零点;而在其余270°范围内允许出现零点,且正西和西南方向必须为零。为此,设计了一个由4个铅垂铁塔组成的阵列,各铁塔上的电流幅度相等,相位关系可自由调整,几何布置和间距不受限制。设计过程如下: 第一步:构建初级波瓣图 选取南北方向上的两个点源,间距为0.2λ(λ为电磁波波长),形成一个端射阵。通过调整相位差,使正南方向的辐射为零,计算得到初始相位差δ=252°。为了满足西南方向零辐射的要求,整体相位再偏移45°,得到初级波瓣图的表达式为E1=cos(36°cos(φ+45°)+126°)。 第二步:构建次级波瓣图 再选取一个点源位于正北方向,另一个点源位于西南方向,间距为0.4λ。调整相位差使西南方向的辐射为零,计算得到相位差δ=280°。同样整体偏移45°,得到次级波瓣图的表达式为E2=cos(72°cos(φ+45°)+140°)。 最终组合: 将初级波瓣图E1和次级波瓣图E2相乘,得到总阵的波瓣图E=E1×E2=cos(36°cos(φ+45°)+126°)×cos(72°cos(φ+45°)+140°)。通过编程实现计算并绘制波瓣图,可以看到三个阶段的波瓣图分别对应初级波瓣、次级波瓣和总波瓣,最终得到满足广播电台需求的总波瓣图。实验代码使用MATLAB编写,利用polar函数在极坐标下绘制波瓣图,并通过subplot分块显示不同阶段的波瓣图。这种设计方法体现了天线阵列设计的基本原理,即通过调整天线间的相对位置和相位关系,控制电磁波的辐射方向和强度,以满足特定的覆盖需求。这种设计在雷达、卫星通信和移动通信基站等无线通信系统中得到了广泛应用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值