{"msg":"操作成功","code":200,"data":{"createBy":"admin","createTime":"2021-02-27 22:45:40","updateBy":"admin","updateTime":"2025-06-16 20:20:34","remark":null,"id":52,"articleTitle":"Shell（十一）文本处理sed命令","articleUrl":"shell_sed","articleThumbnail":"https://www.asumimoe.com/imgfiles/20220908/7769fde9ec5445068e41583cb1c71894.jpg","articleFlag":"0","draftStatus":"1","reprintStatement":"1","articleSummary":"sed（Stream EDitor）是一个强大而简单的文本解析转换工具，可以读取文本，并根据指定的条件对文本内容进行编辑（删除、替换、添加、移动等），最后输出所有行或者仅输出处理的某些行。sed也可以在无交互的情况下实现相当复杂的文本处理操作，被广泛应用于Shell脚本中，用以完成各种自动化处理任务。","articleContent":"## sed命令\n\nsed（Stream EDitor）是一个强大而简单的文本解析转换工具，可以读取文本，并根据指定的条件对文本内容进行编辑（删除、替换、添加、移动等），最后输出所有行或者仅输出处理的某些行。sed也可以在无交互的情况下实现相当复杂的文本处理操作，被广泛应用于Shell脚本中，用以完成各种自动化处理任务。\nsed 的工作流程主要包括读取、执行和显示三个过程。\n读取：sed 从输入流（文件、管道、标准输入）中读取一行内容并存储到临时的缓冲区中（又称模式空间，pattern space）。\n执行：默认情况下，所有的 sed 命令都在模式空间中顺序地执行，除非指定了行的地址，否则 sed 命令将会在所有的行上依次执行。\n显示：发送修改后的内容到输出流。在发送数据后，模式空间将会被清空。\n在所有的文件内容都被处理完成之前，上述过程将重复执行，直至所有内容被处理完。\n\n注意：默认情况下所有的 sed 命令都是在模式空间内执行的，因此输入的文件并不会发生任何变化，除非是用重定向存储输出。\n\n### sed格式\n\n```bash\nsed的命令格式：sed [选项]  [sed命令]   [输入文件]\nsed的脚本格式：sed [options] -f [脚本] [输入文件]\n```\n\n### sed常用选项\n\n```bash\n-e ：直接在命令行模式上进行sed动作编辑，此为默认选项\n-f ：将sed的动作写在一个文件内，用–f filename 执行filename内的sed动作\n-i ：直接修改文件内容，不输出到终端\n-n ：只打印模式匹配的行\n-r ：支持扩展表达式\n```\n\n### sed常用命令\n\n```bash\na：追加，在指定行后添加一行或多行文本\ni：当前行上面插入文本\nr：r file 从文件中读取行\nw：将匹配行写到文件末尾\nW：将匹配的第一行追加到文件末尾\nc：取代指定行\ns：替换指定字符\nd：删除指定行\nD：删除模式空间的第一行，开始下一个循环\nI：在指定行前添加指定文本\np：打印模式空间的内容\nP：打印模式空间第一行\nq：立即退出seq脚本\n!：表示后面的命令对所有没有被选定的行发送作用\n=：打印当前行号\n#：把注释扩展到下一个换行符以前\n```\n\n### sed替换标记\n\n```bash\ng：表示行内全面替换\nx：表示互换模板块中的文本和缓冲区中的文本\ny：表示把一个字符翻译为另外的字符（但是不用于正则表达式）\n\\1：子串匹配标记\n&：已匹配字符串标记\n```\n\n### sed地址\n\nsed命令可以在没有地址的情况下给出，在这种情况下，将对所有输入行执行命令；具有一个地址，在这种情况下，该命令将仅对以下输入行执行：匹配该地址；具有两个地址，在这种情况下，将对所有输入行执行命令，这些输入行与从第一个地址开始并继续到第二个地址。\n\n```bash\nfirst~step：这两个单词的意思：first指起始匹配行，step指步长，例如：sed-n2~5p含义：从第二行开始匹配，隔5行匹配一次，即2,7,12.......。\n$：这个$符表示匹配最后一行。\n/REGEXP/：这个是表示匹配正则那一行，通过//之间的正则来匹配。\n\\cREGEXPc：这个是表示匹配正则那一行，通过\\c和c之间的正则来匹配,c可以是任一字符\naddr1,add2：地址addr1，add2决定用于对哪些行进行编辑。地址的形式可以是数字、正则表达式或二者的结合。\n如果没有指定地址，sed将处理输入文件中的所有行。如果定址是一个数字，则这个数字代表行号，如果是逗号分隔的两个行号，那么需要处理的定址就是两行之间的范围（包括两行在内）。范围可以是数字，正则或二者组合。\naddr1,+N：从addr1这行到往下N行匹配，总共匹配N+1行\naddr1,~N：从addr1这行到往下直到下一行的行号为N的倍数，\n```\n\n## sed常用示例\n\n### 打印指定行\n\n打印第一到第三行\n\n```bash\n[root@l1 ~]# sed -n '1,3p' passwd \nroot:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:/sbin/nologin\ndaemon:x:2:2:daemon:/sbin:/sbin/nologin\n```\n\n打印以root开头的行\n\n```bash\n[root@l1 ~]# sed -n '/^root/p' passwd \nroot:x:0:0:root:/root:/bin/bash\n```\n\n打印包含root的行的行号，及内容\n\n```bash\n[root@l1 ~]# sed -n '/root/=' passwd \n1\n10\n```\n\n截取日志中指定时间段的日志\n\n```bash\nsed '/2020-09-14T00:22:38/,/2020-09-14T01:22:38/p 1.log' access.log\n```\n\n### 文件中插入行\n\n向包含root的行后插入一行`behindroot`，在匹配行之前插入则为i选项\n\n```bash\n[root@l1 ~]# sed '/root/a behindroot' passwd \nroot:x:0:0:root:/root:/bin/bash\nbehindroot\noperator:x:11:0:operator:/root:/sbin/nologin\nbehindroot\n```\n\n像文件末尾加入1.sh中的内容\n\n```bash\n[root@l1 ~]# sed '$r 1.sh' passwd\nmysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/false\n#/bin/bash\nA=`ps -C nginx --no-header | wc -l`\nif [ $A -ne 0 ];then\n\t/usr/local/nginx/sbin/nginx\n\tsleep 2\nfi\n```\n\n### 替换文件内容\n\n整行替换，将1-3行替换为123456\n\n```bash\n[root@l1 ~]# sed '1,3c 123456' passwd \n123456\nadm:x:3:4:adm:/var/adm:/sbin/nologin\n```\n\n替换指定字符，将含有root行的第一个root替换为pass\n\n```bash\n[root@l1 ~]# sed '/root/{s/root/pass/}' passwd\npass:x:0:0:root:/root:/bin/bash\nbin:x:1:1:bin:/bin:/sbin/nologin\n```\n\n每一行的末尾加上hello\n\n```bash\n[root@l1 ~]# sed 's/$/&hello/' passwd \nroot:x:0:0:root:/root:/bin/bashhello\nbin:x:1:1:bin:/bin:/sbin/nologinhello\ndaemon:x:2:2:daemon:/sbin:/sbin/nologinhello\n```\n\n文档内容添加注释\n\n```bash\n# 第3行添加注释\nsed -i '3s/^/#/' /etc/rc.d/rc.local\n\n# 带start的行添加注释\nsed -i '/start/ s/^/#/' /etc/rc.d/rc.local\n```\n\n### 删除文件内容\n\n删除不包含root的行\n\n```bash\n[root@l1 ~]# sed  '/root/!d' passwd \nroot:x:0:0:root:/root:/bin/bash\noperator:x:11:0:operator:/root:/sbin/nologin\n```\n\n### 引用变量\n\nsed命令使用单引号的情况下，变量要用单引号加双引号引用。\n\nsed命令使用双引号的情况下，直接`shell command`或者`$(shell command)`引用命令执行。\n\n```bash\nsed \"s/$a/$b/\" filename\nsed 's/'\"$a\"'/'\"$b\"'/ filename \n```\n\n### 位置调换\n\n```bash\n#替换x字符为大写： \necho \"abc cde xyz\" |sed -r 's/(.*)x/\\1X/' \nabc cde Xyz \n#456与cde调换： \necho \"abc:cde;123:456\" |sed -r 's/([^:]+)(;.*:)([^:]+$)/\\3\\2\\1/' \nabc:456;123:cde\n```","categoryId":5,"viewCount":869,"categoryName":"Shell","author":"球接子","authorAvatar":null,"tagIds":[4,10],"tagNames":["Shell","Linux基础"]}}