Sed命令学习

 相关链接:

                         sed之G、H、g、h使用

                         sed之H与h的妙用

                         sed之lable使用详解

                         sed n和N区别


1.Sed 简介

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

        sed在正常情况下,将处理的行读入模式空间(pattern space),脚本中的“sed-command(sed命令)”就一条接着一条进行处理,知道脚本执行完毕。然后该行被输出,模式(pattern space)被清空;接着,在重复执行刚才的动作,文件中的新的一行被读入,直到文件处理完毕。

        

        什么是Pattern Space,什么是Hold Space?

        pattern space相当于车间sed把流内容在这里处理。

        hold space相当于仓库,加工的半成品在这里临时储存。

        PS:你可以将pattern space看成是一个流水线,所有的动作都是在“流水线”上执行的;而hold space是一个“仓库”,“流水线”上的东东都可以放到这里。

        

        举个比较常见的使用sed例子:替换文件内容

                sed -i 's/被替换的内容/要替换的内容/g' file (sed -i 'n,m s/被替换的内容/要替换的内容/g' file)

        这里要注意的是:

        不能这样做:

               sed 's/被替换的内容/要替换的内容/g' file > file

        这样只会清空源文件

2.选项

        -e command, --expression=command 

        允许多台编辑

        -h, --help

        打印帮助,并显示bug列表的地址。

        -n, --quiet, --silent

        取消默认输出。

        -f, --filer=script-file

        引导sed脚本文件名。

        -V, --version 

        打印版本和版权信息。

3.定址

        可以通过定址来定位你所希望编辑的行,该地址用数字构成,用逗号分割两个行数表示以这两行为起始的行的范围(包括行数表示的那两行)。如1,3表示1,2,3行,美元符号($)表示最后一行。
        范围可以通过数据,正则表达式或者二者结合的方式确定。


4.Sed命令

        调用Sed命令有两种形式:
                 sed [options] 'command' file(s)
                 sed [options] -f scriptfile file(s)

--------------------------------------------------------------------------------------------------------

        a\

        在当前行后面加入一行文本。

        eg:

        $cat source

         line1

         line2

         line3

         1.在第一行和第二行之间添加一行内容为"append line"的行

                  sed '1 a\append line' source

         2.在第一行和第二行后面都新这增一行内容为"append line"的行

                  sed '1,2 a\append line' source

         3.在所有行后面都新增一行内容为"append line"的行

                  sed 'a\append line' source

--------------------------------------------------------------------------------------------------------

        b label

        分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾

        eg:

        $cat file

        AA 
        BC
        AA 
        CB
        CC
        AA

        1.修改文件内容在行中包含"AA"字符串的末尾添加" YES",而没有包含"AA"的字符串在末尾添加" NO YES"

                sed '/AA/ b label1; s/$/ NO/; :label1; s/$/ YES/' file

        执行结果:

        AA YES
        BC NO YES
        AA YES
        CB NO YES
        CC NO YES
        AA YES

       注释:

        #匹配到AA时,"b"跳到标签label1处,执行label1后面的语句 s/$/ YES/ (":"是申明标签)

        #未匹配到AA的行时,就会执行 s/$/ NO/ 并且还会继续执行后面的命令 s/$/ YES/

        2.修改文件内容在行中包含"AA"字符串的末尾添加" YES",而没有包含"AA"的字符串在末尾只添加" NO"

                sed '/AA/ b label1; s/$/ NO/; b; :label1; s/$/ YES/' file

        执行结果:

        AA YES
        BC NO
        AA YES
        CB NO
        CC NO
        AA YES

        注释:

        #匹配到行中包含AA时,"b"跳转到标签label1处,执行 s/$/ YES/

        #未匹配到包含AA的行时,执行s/$/ NO/,然后"b"跳转到""处,而""标签不存在则跳到脚本行末尾,就跳过了s/$/ YES命令了。

--------------------------------------------------------------------------------------------------------

        t label

        if分支,从最后一行开始,条件一旦满足, t命令将导致分支带到有标号的命令处,或者到脚本的末尾

        eg:

        $cat file

        AA
        BC
        AA
        CB
        CC
        AA

        1.修改文件内容在行中包含"AA"字符串的末尾添加" YES",而没有包含"AA"的字符串在末尾添加" NO"

                sed '/AA/ s/$/ YES/; t; s/$/ NO/' file

        输出结果:

        AA YES
        BC NO
        AA YES
        CB NO
        CC NO
        AA YES
        注释:
        #当行中匹配到AA时,执行's/$/ YES/',然后进入"t",因为"t"之前的一行是'/AA/ s/$/ YES/' 条件是满足的,因此"t" 跳到""标签处,而""标签不存在,因此跳到脚本末尾,结束。
        #当行中没有匹配到AA时,"t"失效,则会执行 's/$/ NO'命令

--------------------------------------------------------------------------------------------------------

        T label

        错误分支,从最后一行开始,一旦发生错误,T命令将导致分支带到有标号的命令处或者到脚本的末尾。
        2.修改文件内容在行中包含"AA"字符串的末尾添加" YES NO",而没有包含"AA"的字符串在末尾添加""
                sed '/AA/ s/$/ YES/; T; s/$/ NO/' file
        输出结果:
        AA YES NO
        BC
        AA YES NO
        CB
        CC
        AA YES NO
        #完全可以不用"T"就可以达到目的,这里只是要体现"T"的作用
        #当行中匹配到AA时,执行's/$/ YES/',然后"T"失效再执行's/$/ NO/'.
        #当行中没有匹配到AA时,"T"生效,"T"将分支跳到""标签处,而""并不存在因此跳到脚本末尾,结束。

--------------------------------------------------------------------------------------------------------

        c\

        用新的文本改变本行的文本
        eg:
        $cat file
        AA
        BC
        AA
        CB
        CC
        AA
        1.将包含"AA"字符串的行替换为"BB"
                sed '/AA/ c\BB' file
        输出结果:
        BB
        BC
        BB
        CB
        CC
        BB         
        2.将1-3行的内容替换成"BB"
                sed '1,3 c\BB' file

--------------------------------------------------------------------------------------------------------

        d

        从莫板块(Pattern sapce)位置删除
        eg: 
        file 内容为:
        AA
        BC
        AA
        CB
        CC
        AA
        1.删除所有行
                sed 'd' file
        2.删除文本中的第1-3行
                sed '1,3d' file

--------------------------------------------------------------------------------------------------------

        D

        删除模版块的第一行
        1.删除所有行
                sed 'D' file
        2.删除文本中的第1-3行
                sed '1,3D' file

--------------------------------------------------------------------------------------------------------

        d 以及 D 参数的比较

        [address1, address2]D
        对上述格式说明:函数参数D最多匹配两个地址参数.
        函数参数D与d的比较如下:
        1.当pattern space 内只有一行数据的时候,D 与 d的作用相同
        2.当pattern space 内有多行资料时
        D表示只删除pattern space内的第一行资料, d则全删除
        D表示执行删除后,pattern space 内不添加下一条数据,而将剩下的数据重新执行sed script; d则读入下一条后再执行sed script

        例如:

This line is followed by 1 blank line. 

This line is followed by 2 blank lines. 


This line is followed by 3 blank lines. 



This line is followed by 4 blank lines. 




This is the end. 

        我想得到的效果是

This line is followed by 1 blank line. 

This line is followed by 2 blank lines. 

This line is followed by 3 blank lines. 

This line is followed by 4 blank lines. 

This is the end. 

        代码如下
        
        /^$/{ 
        N 
        /^\n$/d 
        } 
        执行后效果如下

This line is followed by 1 blank line. 
 
This line is followed by 2 blank lines. 
This line is followed by 3 blank lines. 
 
This line is followed by 4 blank lines. 
This is the end. 

        这个过程是这样的  sed是一行一行读入数据的,
        首先读入第一行,因为并不匹配,所以直接打印出来,如下:

This line is followed by 1 blank line.
        然后读入第二行,匹配,所以N继续读入第三行,然后再与/^\n$/进行匹配,很明显不匹配,所以内容也直接打印出来,如下:
This line is followed by 1 blank line. 
 
This line is followed by 2 blank lines. 

        接着读入第四行,匹配,所以N继续读入第5行,然后与/^\n$/进行匹配,因为此时读入的为2个空行,显然是匹配的这时候此2行被删除,所以此时打印的结果依旧如上。
        接着再读入第5行,不匹配,直接打印出来,如下:

This line is followed by 1 blank line. 
 
This line is followed by 2 blank lines. 
This line is followed by 3 blank lines. 

        接着读入第6行,匹配,N继续读入第7行,显然继续匹配,所以次2行被删除
        接着读入8行,匹配,N继续读入第9行,不匹配,所以把第8 9行打印出来,如下

This line is followed by 1 blank line. 
 
This line is followed by 2 blank lines. 
This line is followed by 3 blank lines. 
 
This line is followed by 4 blank lines. 

        接着读入第10行,匹配,N继续读入第11行,显然继续匹配,所以次2行被删除
        接着读入第12行,匹配,N继续读入第13行,显然继续匹配,所以次2行被删除
        最后读入最后14行,不匹配,直接打印,如下:

This line is followed by 1 blank line. 
 
This line is followed by 2 blank lines. 
This line is followed by 3 blank lines. 
 
This line is followed by 4 blank lines. 
This is the end. 

        而代码使用D
        代码如下
        
        /^$/{ 
        N 
        /^\n$/D 
        } 
        他的流程就不同了
         
        首先读入第一行,因为并不匹配,所以直接打印出来,如下:

This line is followed by 1 blank line. 

        然后读入第二行,匹配,所以N继续读入第三行,然后再与/^\n$/进行匹配,很明显不匹配,所以内容也直接打印出来,如下:

This line is followed by 1 blank line. 
 
This line is followed by 2 blank lines. 

        接着读入第四行,匹配,所以N继续读入第5行,然后与/^\n$/进行匹配,因为此时读入的为2个空行,显然是匹配的,所以D把第4行删除,剩下第5行,但是此时第5行并不会打印出来,而是作为读入,继续运行这个脚本,也就是说第5行又先匹配/^$/,然后执行N,读入第6行,而此时内容已经不匹配/^\n$/,这样第5行和第6行就直接打印出来了,如下:

This line is followed by 1 blank line. 
 
This line is followed by 2 blank lines. 
 
This line is followed by 3 blank lines. 

        接着读入第7行,此时匹配,然后N继续读入第8行,依旧匹配,所以执行D,删除第7行,而第8行继续匹配,重新执行脚本,N继续读入第9行,此时依旧匹配,所以删除第8行,第9行继续匹配,N读入第10行,而此时不再匹配,所以打印出第9和10行,如下:

This line is followed by 1 blank line. 
 
This line is followed by 2 blank lines. 
 
This line is followed by 3 blank lines. 
 
This line is followed by 4 blank line. 

        然后读入11直到最后一行,最后得到所需要的结果

This line is followed by 1 blank line. 
 
This line is followed by 2 blank lines. 
 
This line is followed by 3 blank lines.  
 
This line is followed by 4 blank line.  
 
This is the end. 

--------------------------------------------------------------------------------------------------------

        i\

        在当前行插入文本
        eg:
        $cat file
        AA
        BC
        AA
        CB
        CC
        AA
        1.在所有行之前都加上一行内容为"insert line"的行
                sed 'i\insert line' file
        输出结果:
        insert line
        AA
        insert line
        BC
        insert line
        AA
        insert line
        CB
        insert line
        CC
        insert line
        AA
        2.在1-3行每一行之前加上一行内容为"insert line"的行
                sed '1,3 i\insert line' file
        输出结果为:
        insert line
        AA
        insert line
        BC
        insert line
        AA
        CB
        CC
        AA

--------------------------------------------------------------------------------------------------------

        h

        拷贝模版块(pattern space)中的内容到缓冲区(hold space)中,hold space内容将被清空重新赋值

--------------------------------------------------------------------------------------------------------

        H

        追加模版块(pattern space)中的内容到缓冲区(hold space)中

--------------------------------------------------------------------------------------------------------

        h 和 H 参数实例

        $cat file
        1
        2
        foo
        3
        4
        5
        foo
        6
        7
        8
        要得到最后一个foo以后的内容
        foo
        6
        7
        8
        
                sed -n 'H;/foo/{h};${x;p}' file
                
        注释:
        #H 把每一行的内容都追加进内存的缓冲区当中,当遇到foo时,则将foo替代内存缓冲区中的文本,把之前追加的内容都清空了,用foo覆盖了
        #里面的所有内容,那匹配到最后一个foo的时候就肯定覆盖了之前的所有追加的内容了,直到文件最后,x交换出内存缓冲区中的内容,然后打印
        # -n 是取消默认输出,由p输出,表示互换模板块中的文本(pattern space)和缓冲区中的文本(hold space)。
        也可以用awk命令实现:
                awk 'BEGIN{while(getline < "file") {j++; if(/foo/)i=j}}NR>=i' file
        注释:
        #awk是在BEGIN中先找出最后一个foo的行,然后打印这个行以后的内容
        #如果要是只打印foo之后的行(不包含foo)呢?awk很好该,NR>i就行了,sed呢?加一个n,匹配到foo时就读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
        
        sed -n 'H;/foo/{n;h};${x;p}' file
        awk 'BEGIN{while(getline< "file"){j++; if(/foo/)i=j}}NR>i' file
--------------------------------------------------------------------------------------------------------
        g
        拷贝缓冲区(hold space)中的内容到模版块(pattern space)中,原模版块中的内容将被清空.

--------------------------------------------------------------------------------------------------------

        G

        追加缓冲区(hold space)中的内容到模版块(pattern space)中。

--------------------------------------------------------------------------------------------------------

        h,H,g,G 的使用

        + g:[address[,address]]g 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
        + G:[address[,address]]G 将hold space中的内容append到pattern space\n后
        + h:[address[,address]]h 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
        + H:[address[,address]]H 将pattern space中的内容append到hold space\n后
        + d:[address[,address]]d 删除pattern中的所有行,并读入下一新行到pattern中
        + D:[address[,address]]D 删除multiline pattern中的第一行,不读入下一行


        PS:不论是使用G、g还是H、h,它们都是将hold space里面的内容“copy”到pattern space中或者将pattern space中的内容“copy”到hold space中。


        eg:
        用sed模拟出tac的功能(倒序输出)
        $cat file
        1
        2
        3
        命令: sed '1!G;h;$!d' file
        注释:
        #1!G 是指第一行不执行"G"命令,从第二行开始
        #$!d 是指会后一行不删除pattern space中的内容
        图解分析:
        P:Pattern Space
        H:Hold Space
        蓝色:Hold Space中的数据
        绿色:Pattern Space中的数据

        

--------------------------------------------------------------------------------------------------------

        l

        列表不能打印字符的清单,它会以两位数的ASSCII码,展现那些不能打印出来的字符。它有点像vi里面的列表命令(:l)
        eg: cat file
        Here is a string of special characters:^A ^B ^M ^G
        sed "l" file
        Here is a string of special characters:\01 \02 \15 \07

--------------------------------------------------------------------------------------------------------

        n

        读取下一行输入行,用下一个命令处理新的行而不是用第一个命令。

--------------------------------------------------------------------------------------------------------

        N

        追加下一个输入行到莫板块后年并在两者间嵌入一个新行,改变当前行号码。
--------------------------------------------------------------------------------------------------------

        sed n和N区别

        echo -e "1\n2\n3\n4"的结果是:
        1
        2
        3
        4
        echo -e "1\n2\n3\n4" | sed -n 'N;s/\n/ /;p'
        打印结果是:
        1 2
        3 4
        注释:
        #sed先读入第一行到pattern space,然后执行N命令,将第二行追加进pattern space
        #这时pattern space里面就是1\n2,然后执行s/\n/ /,将换行符替换成空格,最后打印。
        
        echo -e "1\n2\n3\n4" | sed -n 'n;s/\n/ /;p'
        打印结果:
        2
        4
        注释:
        #sed先读入第一行到pattern space,然后执行n命令,用第二行覆盖pattern space
        #这时pattern space里面就是2,然后执行s/\n/ /,因为pattern space里没有\n,所以不做任何替换,直接打印。

--------------------------------------------------------------------------------------------------------

       

        打印模板块的行。

--------------------------------------------------------------------------------------------------------

        P(大写) 

        打印模板块的第一行。
--------------------------------------------------------------------------------------------------------

        r file 

        从file中读行。
--------------------------------------------------------------------------------------------------------

        w file 

        写并追加模板块到file末尾。
--------------------------------------------------------------------------------------------------------

        W file 

        写并追加模板块的第一行到file末尾。
--------------------------------------------------------------------------------------------------------

        ! 

        表示后面的命令对所有没有被选定的行发生作用。
--------------------------------------------------------------------------------------------------------

        s/re/string 

        用string替换正则表达式re。
--------------------------------------------------------------------------------------------------------

       

        打印当前行号码。
        eg:
        $cat file
        a
        b
        c
        d
        sed -n = file    or sed -n '=' file
        打印结果:
        1
        2
        3
        4
        
        eg:在每一行前加上行号,并用":"分隔开
        $cat file
        a
        b
        c
        d
        sed '=' file| sed 'N;s/\n/:/'


        打印结果:
        1:a
        2:b
        3:c
        4:d
--------------------------------------------------------------------------------------------------------

       

        把注释扩展到下一个换行符以前。

--------------------------------------------------------------------------------------------------------

        替换标记


        g

        表示行内全面替换。
        cat file
        a  b
        b
        c
        d
        a  b  a
        sed 's/a/A/g' file
        打印结果:
        A  b
        b
        c
        d
        A  b  A


        p

        表示打印行。
        sed 's/b/B/p' file
        打印结果:
        a  B
        a  B
        B
        B
        c
        c
        d
        d
        a  B  a
        a  B  a


        w

        表示把行写入一个文件。
        sed 's/b/B/w temp' file
        cat temp
        打印结果:
        a  B
        B
        c
        d
        a  B  a


        x

        表示互换模板块中的文本和缓冲区中的文本。

        y

        表示把一个字符翻译为另外的字符(但是不用于正则表达式)

--------------------------------------------------------------------------------------------------------

5. 元字符集

        

        锚定行的开始 如:/^sed/匹配所有以sed开头的行。


        

        锚定行的结束 如:/sed$/匹配所有以sed结尾的行。


        

        匹配一个非换行符的字符 如:/s.d/匹配s后接一个任意字符,然后是d。


        

        匹配零或多个字符 如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。


        [] 

        匹配一个指定范围内的字符,如/[Ss]ed/匹配sed和Sed。


        [^] 

        匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。


        \(..\) 

        保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。


        

        保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。


        \< 

        锚定单词的开始,如:/\<love/匹配包含以love开头的单词的行。


        \> 

        锚定单词的结束,如/love\>/匹配包含以love结尾的单词的行。


        x\{m\} 

        重复字符x,m次,如:/o\{5\}/匹配包含5个o的行。


        x\{m,\} 

        重复字符x,至少m次,如:/o\{5,\}/匹配至少有5个o的行。


        x\{m,n\} 

        重复字符x,至少m次,不多于n次,如:/o\{5,10\}/匹配5--10个o的行。


6.应用举例

        删除:d命令 
        $ sed '2d' example-----删除example文件的第二行。
        $ sed '2,$d' example-----删除example文件的第二行到末尾所有行。
        $ sed '$d' example-----删除example文件的最后一行。
        $ sed '/test/d' example-----删除example文件所有包含test的行。
        
        替换:s命令 
        $ sed 's/test/mytest/g' example-----在整行范围内把test替换为mytest。如果没有g标记,则只有每行第一个匹配的test被替换成mytest。
        $ sed -n 's/^test/mytest/p' example-----(-n)选项和p标志一起使用表示只打印那些发生替换的行。也就是说,如果某一行开头的test被替换成mytest,就打印它。
        $ sed 's/^192.168.0.1/&localhost/' example-----&符号表示替换换字符串中被找到的部份。所有以192.168.0.1开头的行都会被替换成它自已加 localhost,变成192.168.0.1localhost。
        $ sed -n 's/\(love\)able/\1rs/p' example-----love被标记为1,所有loveable会被替换成lovers,而且替换的行会被打印出来。
        $ sed 's#10#100#g' example-----不论什么字符,紧跟着s命令的都被认为是新的分隔符,所以,“#”在这里是分隔符,代替了默认的“/”分隔符。表示把所有10替换成100。
        
        选定行的范围:逗号
        $ sed -n '/test/,/check/p' example-----所有在模板test和check所确定的范围内的行都被打印。
        $ sed -n '5,/^test/p' example-----打印从第五行开始到第一个包含以test开始的行之间的所有行。
        $ sed '/test/,/check/s/$/sed test/' example-----对于模板test和west之间的行,每行的末尾用字符串sed test替换。
        
        多点编辑:e命令
        $ sed -e '1,5d' -e 's/test/check/' example-----(-e)选项允许在同一行里执行多条命令。如例子所示,第一条命令删除1至5行,第二条命令用check替换test。命令的执 行顺序对结果有影        响。如果两个命令都是替换命令,那么第一个替换命令将影响第二个替换命令的结果。
        $ sed --expression='s/test/check/' --expression='/love/d' example-----一个比-e更好的命令是--expression。它能给sed表达式赋值。
        
        从文件读入:r命令
        $ sed '/test/r file' example-----file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面。


        写入文件:w命令 
        $ sed -n '/test/w file' example-----在example中所有包含test的行都被写入file里。

        追加命令:a命令 
        $ sed '/^test/a\\--->this is a example' example<-----'this is a example'被追加到以test开头的行后面,sed要求命令a后面有一个反斜杠。


        插入:i命令 
        $ sed '/test/i\\
        new line
        -------------------------' example


        如果test被匹配,则把反斜杠后面的文本插入到匹配行的前面。


        下一个:n命令 
        $ sed '/test/{ n; s/aa/bb/; }' example-----如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行,然后继续。


        变形:y命令
        $ sed '1,10y/abcde/ABCDE/' example-----把1--10行内所有abcde转变为大写,注意,正则表达式元字符不能使用这个命令。


        退出:q命令 
        $ sed '10q' example-----打印完第10行后,退出sed。会打印前10行


        保持和获取:h命令和G命令 
        $ sed -e '/test/h' -e '$G example-----在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将 打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理。在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保 持缓存区的特殊缓冲区内。第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中 的行的末尾。在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。


        保持和互换:h命令和x命令 
        $ sed -e '/test/h' -e '/check/x' example -----互换模式空间和保持缓冲区的内容。也就是把包含test与check的行互换。


7. 脚本

        Sed脚本是一个sed的命令清单,启动Sed时以-f选项引导脚本文件名。Sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。以#开        头的行为注释行,且不能跨行。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值