目录导航
Sed简介
sed是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并没有 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操作;编写转换程序等。
sed用法
用法: sed [选项]... {脚本(如果没有其他脚本)} [输入文件]...
-n, --quiet, --silent
取消自动打印模式空间
--debug
对程序运行进行标注
-e 脚本, --expression=脚本
添加“脚本”到程序的运行列表
-f 脚本文件, --file=脚本文件
添加“脚本文件”到程序的运行列表
--follow-symlinks
直接修改文件时跟随软链接
-i[扩展名], --in-place[=扩展名]
直接修改文件(如果指定扩展名则备份文件)
-l N, --line-length=N
指定“l”命令的换行期望长度
--posix
关闭所有 GNU 扩展
-E, -r, --regexp-extended
在脚本中使用扩展正则表达式
(为保证可移植性使用 POSIX -E)。
-s, --separate
将输入文件视为各个独立的文件而不是单个
长的连续输入流。
--sandbox
在沙盒模式中进行操作(禁用 e/r/w 命令)。
-u, --unbuffered
从输入文件读取最少的数据,更频繁的刷新输出
-z, --null-data
使用 NUL 字符分隔各行
--help 打印帮助并退出
--version 输出版本信息并退出
如果没有 -e, --expression, -f 或 --file 选项,那么第一个非选项参数被视为
sed脚本。其他非选项参数被视为输入文件,如果没有输入文件,那么程序将从标准
输入读取数据。
GNU sed 主页:<https://www.gnu.org/software/sed/>。
使用 GNU 软件的一般性帮助:<https://www.gnu.org/gethelp/>。
推荐书籍(不是我写的)
sed 权威指南 – Daniel Goldman
Sed & Awk – Dale Dougherty & Arnold Robbins
有效的 awk 编程 – Arnold Robbins
带简短说明的 一行
打印第十行的数据
sed -n '10p' php.py
对除第 5 行以外的所有行进行替换
sed '5!/s/foo/bar/' php.py
在匹配正则表达式的行上进行替换(例如:以 ‘hello’ 开头的行)
sed '/^hello/ s/h/H/' file.txt
从第 5 行到文件末尾进行替换
sed '5,$ s/foo/bar/' file.txt
删除空文件
sed '/^$/d' file
在两个正则表达式匹配之间打印行
sed -nE '/^foo/,/^bar/p' file.txt
使用自定义分隔符,方便一些包含斜杠的字符串
sed 's_/bin/bash_/bin/sh_' file.txt
正则表达式地址的自定义分隔符与替代命令的经典分隔符相结合(您也可以在那里使用自定义分隔符)。对路径有用。
sed '\_/bin/bash_s/grep/egrep/' file.txt
- 或者为了清楚起见使用相同的分隔符
sed '\_/bin/bash_s_grep_egrep_' file.txt
使用 & (代表正则表达式匹配)在小写/大写字符之间插入一个空格
sed 's/[a-zA-Z]/& /g' file.txt
保留每一行的第一个单词(为简单起见,单词由字母数字字符 + 下划线定义)
sed -E 's_[a-zA-Z0-9_]+.*_\1_' file.txt
切换前两个词
sed -E 's_([a-zA-Z0-9_]*) ([a-zA-Z0-9_]*)_\2 \1_' f1
删除由单个空格分隔的重复单词(但不是一式三份)
sed -E 's_([a-zA-Z0-9_]+) \1_\1_ig' f1
搜索和替换模式,在新文件中只写替换行
sed 's_foo_bar_w replaced.txt' file.txt
多次更换
sed -e 's_foo_bar_' -e 's_hello_HELLO_' file.txt
使用 sed 脚本进行多次替换
#!/usr/bin/sed -f
s/a/A/
s/foo/BAR/
s/hello/HELLO/
- 使可执行文件
chmod +x myscript.sed
,调用./myscript.sed myfile.txt
使用 ; 的多个命令 理论上连接命令的运算符(警告!对于某些命令,例如“r”或“w”,它不会按预期工作。改用 sed 脚本或将处理文件名的命令放在最后)。打印第 10 行并在第 5 行之前插入。
sed '10p;5i\"INSERTED BEFORE LINE 5" file.txt
删除以这两个关键字开头的行之间的注释。空行将被放置在那里
sed -E '/start/,/end/ s/#.*//' file.txt
删除以 # 开头的注释(不留空行)
sed -E '/^#/d' f1
在模式之后插入一个空行(在这种情况下,在每行包含注释之后)
sed '/^#/G' file.txt
查看行减去从模式开始到文件结尾的行之间的行
sed '/start/,$ d' file.txt
查看除以模式开头的行和以模式结尾的行之间的行之外的行
sed -rn '/start/,/end/ !p' file.txt
打印直到遇到模式然后退出
sed '/start/q' file.txt
在特定行后插入文件内容
sed '5 r newfile.txt' file.txt
在包含正则表达式的行之后附加文本(在 FOO 之后)
sed '/foo/a\AFTER FOO' file.txt
在包含正则表达式的行之后插入文本(BEFORE FOO)
sed '/foo/i\BEFORE FOO' file.txt
更改包含正则表达式匹配的行
sed '/foo/c\FOO IS CHANGED' file.txt
带有反转的嵌套 sed 范围。在第 1,100 行之间应用模式不匹配的操作。
#!/usr/bin/sed -f
1,100 {
/foo/ !{
s_hello_HELLOOOOWORLD_
s_yes_YES_
}
}
使用带有更改、插入和追加的嵌套地址来修改:匹配前的行、匹配的行、匹配后的行。
#!/usr/bin/sed -f
/^#/ {
i\
#BEFFORE ORIGINAL COMMENt
a\
#AFTER ORIGINAL COMMENT
c\
# ORIGINAL COMMENT IS NOW THIS LINE
}
在第一个注释之前插入新行,在第一个注释之后放入文件内容并立即退出
#!/usr/bin/sed -f
/^#/ {
i\#BEFORE COMMENT
r myotherfile.txt
q
}
转换文本
sed 'y/abc/ABC/' file.txt
将所有注释(以 # 开头)复制到一个新文件中
sed -E '/^#/w comments.txt' file.txt
每第二行打印一次(用 ~3 代替第三行等)
sed -n '1~2p' file.txt
就地编辑文件但也创建备份
sed -i.bak 's/hello/HELLO/' file.txt
在正则表达式匹配后附加两行
sed -E '/^#/G G' file.txt
短Sed Tut
sed 命令使用基于它们操作的地址。地址可以是:
单行
– 删除第 10 行
sed '10d' file.txt
行范围 – 从第 1 行到第 10 行删除
sed '1,10d' file.txt
Line range2
– 从第 6 行到文件结尾删除($ 是文件结尾)
sed '6,$d' file.txt
正则表达式– 删除正则表达式匹配的行
sed -E '/^#/d' file.txt
正则表达式范围– 删除正则表达式匹配之间的行(包括正则表达式匹配的行)
sed -E '/DEBUG/,/END_DEBUG/d' file.txt
正则表达式和行范围 – 从匹配 DEBUG 的行删除到第 30 行
sed -E '/DEBUG/,30d' file.txt
所有行 – 在每一行之后附加它(当没有地址时适用于所有行)
sed 'a\AFTER EVERY LINE' file.txt
嵌套– 将其与 sed 脚本一起使用(见下文)
#!/usr/bin/sed -f
1,100 {
/DEBUG/{
/DONE/d
/NOT DONE/a\TO BE DONE URGENTLY
}
}
- 第 1 行和第 100 行之间:
其中匹配调试,
删除包含 /DONE/ 的行并在包含 /NOT DONE/ 的行之后追加。
您可以通过放置一个来反转地址!在命令前面,而不是地址。
sed '/PRODUCTION/!d' file.txt
– 删除所有不包含正则表达式匹配的行。注意!在 d 面前。- 花括号内的所有内容(用于嵌套)都是一个命令。你把!在花括号前面。
#!/usr/bin/sed -f
1,100 {
/DEBUG/ !{
/DONE/d
/NOT DONE/a\TO BE DONE URGENTLY
}
}
- 第 1,100 行之间
在不包含 /DEBUG/ 的行上
执行操作
- “双”嵌套反转
#!/usr/bin/sed -f
1,100 {
/DEBUG/ !{
/DONE/!d
}
}
- 第 1,100 行之间
在不包含 DEBUG 的行上
删除不包含 /DONE/ 的行
基本命令:
5d
–删除– 删除第 5 行。5p
–打印。– 打印第 5 行(-n
当使用 print 仅打印指定的行时,您应该使用选项调用 sed )5q
–退出 – 第 5 行退出后5a\Appended
–追加– 在第 5 行之后。注意 ‘a’ 前面的反斜杠5c\Changed
–更改– 将第 5 行更改为“已更改”5i\Before
–插入– 在第 5 行之前插入。5r newfile.txt
–读取– 将文件 ‘newfile.txt’ 的内容放在第 5 行之后5w written.txt
–写入– 将第 5 行写入 ‘written.txt’5s/foo/bar
–替代– 在第 5 行搜索 foo 并替换为 bar
高级和较少使用的命令
sed -E '/^#/G G' file.txt
–将换行符附加到模式空间,然后将保持空间附加到模式空间– 在与正则表达式匹配的每一行后插入两个空行
正则表达式技巧
&
是匹配的正则表达式。sed -E '/foo/& & &/' file.txt
将三重 foo 词\1
to\9
是组 ID。你使用一个像 `sed -E ‘s/(foo) (bar)/\2 \1’ file.txt ‘ 这样的组。在这个非常简单的例子中,我们搜索“foo”,然后是空格,然后是“bar”。然后我们切换这些词(而不是 ‘foo bar’ 我们有 ‘bar foo’)- Flags。
sed 's/foo/bar/gi' file.txt
. ‘g’ 将替换该行中出现的所有内容(而不是默认情况下的第一个)。’i’ 将使替换不区分大小写。
[未完待续]
关于
这是在重述 sed 的 4-5 小时内诞生的(首先需要很多小时来学习它)。从那以后,我花了更多的时间(和计数)修复和改进。学好东西的一个好方法是向他人解释。老实说,这也是为了我自己,以后,当我忘记时。:)
它在发布后数小时内在 Hacker News 上排名第一,在 Github 上获得了 300 多颗星。小时。该死!所有其他项目的总和(其中一些需要更多时间)都在两位数范围内。低范围。这个快速而肮脏的 sed 提示集合开始流行。我认为自己很幸运能够体验到这一点,我感谢让这一切成为可能的人。为了你,我会尽力把它做得最好。