美文网首页linux basic knowledge
[2020春假]Linux下的文本操作(sed篇)

[2020春假]Linux下的文本操作(sed篇)

作者: 巩翔宇Ibrahimovic | 来源:发表于2020-01-26 21:16 被阅读0次

    Chapter4 sed替换命令详解

    sed的替换命令是最常用的,也是讲解最多的。
    sed的模式空间

    sed的基本工作方式是:

    将文件以行为单位读取到内存(模式空间)

    使用sed的每个脚本对该行进行操作

    处理完成后输出该行

    替换命令s

    sed的替换命令s:

    sed 's/old/new/' filename

    sed -e 's/old/new/' -e 's/old/new/' filename

    sed -i 's/old/new/' 's/old/new/' filename

    带正则表达式的替换命令s

    sed 's/正则表达式/new/'filename

    举例:

    echo a a a > afile
    sed 's/a/aa/' afile #只替换了第一个a,!也可以做分隔符
    sed -e 's/a/aa/' -e 's/aa/bb/' afile
    也可以简写为
    sed 's/a/aa/;s/aa/bb/' afile
    #使用-i写入原始文件
    sed -i 's/a/aa/ ;s/aa/bb/' afile 
    #将三个字符串替换为空
    head -5 /etc/passwd | sed 's/...//' 
    #s出现了1次或0次,只会替换第一次匹配的
    head -5 /etc/passwd | sed 's/s*bin//'
    grep root /etc/passwd | sed 's/^root//'
    

    sed -r 's/扩展正则表达式/new/' filename

    举例:

    cat bfile
    b
    a
    aa
    aaa
    ab
    abb
    abbb
    sed 's/ab*/!/' bfile
    sed -r 's/ab+/!/' bfile #+是扩展元字符,所以要加 -r
    sed -r 's/ab?/!/' bfile
    sed -r 's/(aa)|(bb)/!/' bfile #()是sed独有的,算在扩展元字符里面
    #使用sed里面圆括号的回调功能,\1作为分组
    cat cfile
    axyzb
    sed -r 's/(a.*b)/\1:\1/' cfile
    

    Chapter5 sed替换命令加强版

    全局替换

    s/old/new/g

    g为全局替换,用于替换所有出现的次数。

    / 如果和正则匹配的内容冲突可以使用其他符号,如:s@old@new@g

    head -5 /etc/passwd | sed 's/root/!!!!/g' 
    #只对第二次出现的匹配进行替换,其他的只进行匹配而不替换
    head -5 /etc/passwd | sed 's/root/!!!!/2' 
    

    标志位

    数字,第几次出现才进行替换

    g每次出现都进行替换

    p 打印模式空间的内容(即输出两次,一次是sed的标准输出,二是完成后的输出)

    sed -n 'script' filename 阻止默认输出

    #sed的工作模式是匹配一行输出一行,而使用-n选项阻止默认输出,与p联用则只打印出替换成功的内容
    head -5 /etc/passwd | sed -n's/root/!!!!/p'
    

    w file 将模式空间的内容写入到文件

    head -5 /etc/passwd | sed -n 's/root/!!!!/w /tmp/a.txt' 
    

    寻址

    默认对每行进行操作,增加寻址后对匹配的行进行操作。

    /正则表达式/s/old/new/g

    行号s/old/new/g

    行号可以是具体的行,也可以是最后一行 $ 符号

    可以使用两个寻址符号,也可以混合使用行号和正则地址

    #限制第一行执行
    head -6 /etc/passwd | sed '1s/bin/!/'
    #限制1-3行执行
    head -6 /etc/passwd | sed '1,3s/bin/!/'
    #限制1到最后一行执行
    head -6 /etc/passwd | sed '1,$s/bin/!/'
    #使用正则表达式(root这一行)限制
    head -6 /etc/passwd | sed '/root/s/bash/!/'
    #行号与正则表达式的混用(以bin开头到最后一行的范围)
    head -6 /etc/passwd | sed '/^bin/,$s/nologin/!/'
    

    分组

    寻址可以匹配多条命令,;连接

    /regular/{s/old/new/;s/old/new}

    sed脚本文件

    可以将选项保存为文件,使用-f加载脚本文件

    sed -f sedscript filename

    Chapter 6 sed的其他常用指令

    删除命令

    [寻址]d

    删除模式空间内容,并不是原文件的内容,改变脚本的控制流,读取新的输入行。

    sed '/ab/d' bfile #删除匹配到字符的一整行,与替换不同
    sed '/ab/d;s/a/!/' bfile #一般是先进行替换命令,在进行删除命令,不然删除命令会改变文件原有结构
    

    追加、插入、更改

    追加命令a

    插入命令i

    更改命令c

    #在字符ab的后面添加"hello"
    sed '/ab/a hello' bfile
    #匹配后直接改写字符串
    sed '/ab/c hello' bfile
    

    打印

    打印命令p

    下一行

    下一行命令n

    打印行号命令=

    读文件和写文件

    读文件命令r

    写文件命令w

    #r选项将afile的内容读取到bfile的ab字符串后面,从而完成俩文件的合并
    sed '/ab/r afile' bfile
    

    退出命令

    退出命令q

    哪个效率更高呢?

    #前者更快
    sed 10q filename #只到第十行就停止
    sed -n 1,10p filename #所有行都被会读入内存,但只打印出前十行
    
    seq 1 1000000 > lines.txt
    

    Chapter7 sed多行模式空间

    sed的多行模式

    多行模式处理命令N,D,P

    N将下一行加入到模式空间

    vim a.txt
    hel
    lo
    
    sed 'N;s/hel\nlo/!!!/' a.txt #行与行之间通过换行符\n来连接
    sed 'N;s/hel.lo/!!!/' a.txt 
    

    D删除模式空间中的第一个字符到第一个换行符

    cat > b.txt << EOF
    hell
    o bash hel
    lo bash
    EOF
    sed 'N;s/\n//;s/hello bash/hello sed\n/;P;D' b.txt #其实是用N将1、2行联系起来,将hello bash替换成hello sed,然后打印出来,再删除模式空间第一个字符到第一个换行符。
    

    P打印模式空间中的第一个字符到第一个换行符

    配置文件一般为单行出现

    也有使用XML或JSON格式的配置文件,为多行出现。

    Chapter8 什么是sed的保持空间

    保持空间也是多行的一种操作方式。

    将内容暂存在保持空间,便于做多行处理。

    hH将模式空间内容存放到保持空间(小写是覆盖模式,大写是追加模式)

    gG将保持空间内容取出到模式空间(小写是覆盖模式,大写是追加模式)

    x交换模式空间和保持空间内容

    #将文件内容的前六行进行倒序排列
    cat -n /etc/passwd | head -6 | sed -n '1h;1!G;$!x;$p' #第一行取出到保持空间,不让保持空间的第一行取出到模式空间,不让模式空间最后一行交换,输出最后一行
    #精简1
    cat -n /etc/passwd | head -6 | sed -n 'G;h;$p' #如果不加$p的话,输出内容会有很多
    #精简2,去掉第一行的换行符
    cat -n /etc/passwd | head -6 | sed -n '1!G;h;$p'
    #再精简
    cat -n /etc/passwd | head -6 | sed -n '1!G;h;$!d'
    

    附练习题(来源于https://blog.csdn.net/y1412813204/article/details/86701837
    ):
    测试文件

    Betty Boop:245-836-8357:635 Cutesy Lane, Hollywood, CA 91464:6/23/23:14500
    
    Igor Chevsky:385-375-8395:3567 Populus Place, Caldwell, NJ 23875:6/18/68:23400
    
    Norma Corder:397-857-2735:74 Pine Street, Dearborn, MI 23874:3/28/45:245700
    
    Jennifer Cowan:548-834-2348:583 Laurel Ave., Kingsville, TX 83745:10/1/35:58900
    
    Jon DeLoach:408-253-3122:123 Park St., San Jose, CA 04086:7/25/53:85100
    
    Karen Evich:284-758-2857:23 Edgecliff Place, Lincoln , NB 92743:7/25/53:85100
    
    Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
    
    Karen Evich:284-758-2867:23 Edgecliff Place, Lincoln, NB 92743:11/3/35:58200
    
    Fred Fardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900
    
    Fred Fardbarkle:674-843-1385:20 Parak Lane, Duluth, MN 23850:4/12/23:780900
    
    Lori Gortz:327-832-5728:3465 Mirlo Street, Peabody, MA 34756:10/2/65:35200
    
    Paco Gutierrez:835-365-1284:454 Easy Street, Decatur, IL 75732:2/28/53:123500
    
    Ephram Hardy:293-259-5395:235 CarltonLane, Joliet, IL 73858:8/12/20:56700
    
    James Ikeda:834-938-8376:23445 Aster Ave., Allentown, NJ 83745:12/1/38:45000
    
    Barbara Kertz:385-573-8326:832 Ponce Drive, Gzary, IN 83756:12/1/46:268500
    
    Lesley Kirstin:408-456-1234:4 Harvard Square, Boston, MA 02133:4/22/62:52600
    
    William Kopf:846-836-2837:6937 Ware Road, Milton, PA 93756:9/21/46:43500
    
    Sir Lancelot:837-835-8257:474 Camelot Boulevard, Bath, WY 28356:5/13/69:24500
    
    Jesse Neal:408-233-8971:45 Rose Terrace, San Francisco, CA 92303:2/3/36:25000
    
    Zippy Pinhead:834-823-8319:2356 Bizarro Ave., Farmount, IL 84357:1/1/67:89500
    
    Arthur Putie:923-835-8745:23 Wimp Lane, Kensington, DL 38758:8/31/69:126000
    
    Popeye Sailor:156-454-3322:945 Bluto Street, Anywhere, USA 29358:3/19/35:22350
    
    Jose Santiago:385-898-8357:38 Fife Way, Abilene, TX 39673:1/5/58:95600
    
    Tommy Savage:408-724-0140:1222 Oxbow Court, Sunnyvale, CA 94087:5/19/66:34200
    
    Yukio Takeshida:387-827-1095:13 Uno Lane, Ashville, NC 23556:7/1/29:57000
    
    Vinh Tranh:438-910-7449:8235 Maple Street, Wilmington, VM 29085:9/23/63:68900
    

    将以上文本命名为Week41.config
    以下有九个练习题(附答案)
    1.把Jon的名字改为Jonathan
    2.删除头3行
    3.打印第5~10行

    1. 删除含有Lane的所有行
    2. 打印所有生日在十一月或十二月的行
    3. 在以Kare开头的行末尾加上3颗星
    4. 将所有包含Jose的行都替换为JOSE HAS RETIRED
    5. 删除所有空行

    答案

    1.sed 's/Jon/Jonathan/' Week41.config | grep Jonathan
    2.sed '1,3'd Week41.config | less -SN
    3.sed -n '5,10'p Week41.config
    4.sed '/Lane/'d Week41.config | grep Lane
    5.sed -n '/:1[1,2]\//'p Week41.config
    6.sed '/^Kare/ s/$/ ***/' Week41.config #至于为什么不用管道府和分号目前还不晓得
    7.sed 's/Jose/JOSE/g' Week41.config | grep JOSE
    8. sed -r '/^[[:space:]]*(#|$)/d' Week41.config | less -SN 
    #也可以简写为
    sed -r '/^\s*$/d' Week41.config | less -SN #个人感觉#在这里用处不大
    

    相关文章

      网友评论

        本文标题:[2020春假]Linux下的文本操作(sed篇)

        本文链接:https://www.haomeiwen.com/subject/xxcsthtx.html