-
cut
-
语法
cut option... [file]...
-
理解
可以理解为
split
函数。 -
输入
-
文件
filename
-
标准输入
重定向或
-
-
-
下标选择
-
n
等价于
string.splite(regex)[n]
-
n0,n1,n2...
先对下标进行排序,然后去重,再进行遍历输出。
-
n-m
范围内的输出,包含关系。
-
-n
从1到n
-
n-
从n到末尾,不怕越界,越界为空。
-
-
选项
-
-b byte-list|--bytes=byte-list
按照字节处理
-
-c character-list|--characters=character-list
按照字符处理
-
-f field-list|--fields=field-list
按照自定义分隔符进行分割后的多个单词处理。
-
-d input_delim_byte |-d input_delim_byte
一般和
f
一起使用,用来声明分隔符的。 -
--output-delimiter=output_delim_string
输出的分隔符,默认使用
-d
的分隔符。[root@localhost sed]# echo "hello world" | cut -d ' ' -f1- --output-delimiter='----' hello----world
-
--complement
输出完整的,而不是残缺的。范围选中的不输出。
[root@localhost sed]# ps aux | grep "sshd" | cut --complement -f2- -d ' ' root root root root [root@localhost sed]# ps aux | grep "sshd" | cut --complement -b2- r r r r [root@localhost sed]# ps aux | grep "sshd" | cut --complement -b4- roo roo roo roo [root@localhost sed]# ps aux | grep "sshd" | cut --complement -b5- root root root root [root@localhost sed]# ps aux | grep "sshd" | cut --complement -b8- root root root root [root@localhost sed]# ps aux | grep "sshd" | cut --complement -b5-15 root 0.0 0.4 112924 4296 ? Ss Jun11 0:00 /usr/sbin/sshd -D root 0.0 0.6 163292 6120 ? Ss Jun11 0:01 sshd: root@pts/0 root 0.0 0.6 163292 6116 ? Ss 06:19 0:00 sshd: root@pts/1 root 0.0 0.1 112816 960 pts/1 S+ 07:55 0:00 grep --color=auto sshd [root@localhost sed]# ps aux | grep "sshd" | cut --complement -b120- root 1028 0.0 0.4 112924 4296 ? Ss Jun11 0:00 /usr/sbin/sshd -D root 1434 0.0 0.6 163292 6120 ? Ss Jun11 0:01 sshd: root@pts/0 root 1974 0.0 0.6 163292 6116 ? Ss 06:19 0:00 sshd: root@pts/1 root 2135 0.0 0.1 112816 956 pts/1 S+ 07:56 0:00 grep --color=auto sshd
-
-
-
sed
-
简介
stream editor
,流编辑程序。可以用于处理字符流和字节流。一般用于处理字符串替换。
-
工作原理
-
两个数据缓冲区,开始都为空。处理数据也是一行一行的处理。
-
一个是读取的数据区,一个是辅助存储区。辅助存储区一般没有用。有一些指令会用到。
-
一个周期
- 从字节流中读取一行数据,去除尾部的换行符。保存起来。放在数据缓冲区。
- 然后执行指令,每一个指令都有一个行地址信息。也就是各自处理的行的范围。
- 行是作为筛选的重要条件之一,只有满足的才会执行。比如只处理第一行的,那么其他行的行号不合格就会忽略掉,不执行指令。
- 执行完了所有的指令,如果没有声明
-n
,就会输出结果到标准输出,并且将之前删除的行位添加上。 - 执行完毕,再从第一步开始。每次处理完了之后,数据区的数据都会进行清空,也就是上次读取的一行数据,而数据缓冲区将会保留。当然也有部分的指令可以请求不清除。
-
同时处理多行的指令,大多都是大写,和小写不同的就是可以处理多行。
-
N
添加一行数据到数据区,也就是一次性处理两条数据,中间的换行符也添加进去了。如果没有读取完整就直接退出。不执行任何处理
# 可以通过死循环的方式在一个周期内处理所有的数据。可以结合上面的周期解释进行理解。 [root@localhost sed]# sed -e 'H;s/\n/----/' number.txt 1 2 3 4 5 6 7 8 9 10 [root@localhost sed]# sed -e ':label;N;s/\n/ /;s/ 2$/22222-----/;b label' number.txt 122222----- 3 4 5 6 7 8 9 10 [root@localhost sed]# sed -e 'N;N;s/\n/ /;' number.txt 1 2 3 4 5 6 7 8 9 10 [root@localhost sed]# sed -e 'N;N;s/\n/ /g;' number.txt 1 2 3 4 5 6 7 8 9 10 [root@localhost sed]# sed -e 'N;N;s/\n/ /g;' number.txt 1 2 3 4 5 6 7 8 9 10 [root@localhost sed]# sed -n -e 'N;N;s/\n/ /gp;' number.txt 1 2 3 4 5 6 7 8 9
-
D
清理数据区的内容,并开始下一个周期循环。
# 最后一个因为没有 [root@localhost sed]# sed -e 'N;N;s/\n/ /g;' number.txt 1 2 3 4 5 6 7 8 9 10 [root@localhost sed]# sed -e 'N;N;s/\n/ /g;D;' number.txt 10
-
-
-
输入
-
文件输入
sed SCRIPT INPUTFILE INPUTFILE...
-
重定向
echo hello | sed SCRIPT -
-
-
指令选项
-
sed OPTIONS... [SCRIPT] [INPUTFILE...]
-
-n|--quiet|--silent
- 不输出,除非指令明确的声明。
[root@localhost sed]# sed -e "2,5d" number.txt 1 6 7 8 9 10 [root@localhost sed]# sed -n -e "2,5d" -e "1,5p" number.txt 1 [root@localhost sed]# sed -n -e "2,4d" -e "1,5p" number.txt 1 5 [root@localhost sed]# cat number.txt 1 2 3 4 5 6 7 8 9 10
-
-e script|--expression=script
声明紧接着的字符串按照脚本解析。
-
-f script-file|--file=script-file
脚本从文件中读取。
-
如果没有显示声明脚本,默认使用第一个非选项的字符串作为脚本。
-
-i[SUFFIX]|--in-place[=SUFFIX]
- 将原来的文件添加备份,将处理后的结果作为新的文件。不建议和
-n
搭配,搭配了就是将显式声明的输出结果写入文件。
sed -i.bak -e "s/\(*\)/\1/" number.txt # 等价于 sed -e "s/\(*\)/\1/" number.txt > temp.txt mv number.txt number.txt.bak mv temp.txt number.txt
- 如果没有
suffix
就是处理结果替换源文件。 suffix
里用*
表示源文件名,一个*
表示一个源文件名,多个*
就是多个源文件名。
# 默认后缀 sed -i.bak -e "s/\(*\)/\1/" number.txt # 添加前缀 sed -ibak* -e "s/\(*\)/\1/" number.txt # 多个* sed -i**.bak -e "s/\(*\)/\1/" number.txt #[root@localhost sed]# sed -i**.bak -e "s/\(*\)/\1/" number.txt #[root@localhost sed]# ls #baknumber.txt input.txt number.txt number.txt.bak number.txtnumber.txt.bak
组合选项的时候最好放在
i
前面,不然就会被按照后缀解析。默认添加了-s
选项。 - 将原来的文件添加备份,将处理后的结果作为新的文件。不建议和
-
-E|-r|--regexp-extended
-
加强版正则表达式,支持更多匹配符。
-
默认的是简略版正则。
-
-
-s|--separate
-
默认是将多个文件当成一个文件处理。
-
添加选项后将文件按照多个独立文件处理。
-
-i
选项的时候默认添加了这个选项。
-
-
-
退出码
-
0
表示成功处理完毕。
-
1
表示非法指令,语法错误,正则错误。
-
2
文件读写失败,因为权限问题或没有找到。
-
4
运行时读写错误。
-
自定义
echo | sed ’Q42’ ; echo $? # 退出,并获对应的退出码。
-
-
脚本
-
声明添加方式
5
种,分别为:-e -f --expression --file
和前四个都没有时第一个非选项字符串。 -
脚本的固定格式
[addr]X[options]
# 替换 s为x后面的为options s/aaa// # 指定行替换 1,5就是 addr 1,5s/aaa// #/regex/就是addr,这个是用正则来选择行 /regex/s/aaa//
addr
可以是某一行行号,可以是正则,可以是区间 -
多个脚本
可以在一个字符串里面声明多个脚本,也可以通过多次声明多个脚本。
# 第一个 字符串多个脚本 sed '/^foo/d ; s/hello/world/' input.txt > output.txt # 第二个 多个选项声明多个脚本 sed -e '/^foo/d' -e 's/hello/world/' input.txt > output.txt # 第三个 文件中多行表示多个脚本 echo '/^foo/d' > script.sed echo 's/hello/world/' >> script.sed sed -f script.sed input.txt > output.txt # 第四个 文件和字符串混合声明多个脚本 echo 's/hello/world/' > script2.sed sed -e '/^foo/d' -f script2.sed input.txt > output.txt
-
a,c,i指令因为功能原因,不能用分好作为分隔,所以放在末尾或者文件中声明,或者是换行。
-
声明脚本最好用单引号,不要用双引号。
-
-
脚本之指令|X
-
回顾
指令固定格式
[addr]X[options]
,这小结讲的是支持的指令。-
某一行后插入
a
# 两种格式切记是 atext \ text\ text # a text
案例
[root@localhost sed]# sed -e '2,5ahello' number.txt 1 2 hello 3 hello 4 hello 5 hello 6 7 8 9 10 [root@localhost sed]# sed -e '2,5a\ oknice\ ojbk' number.txt 1 2 oknice ojbk 3 oknice ojbk 4 oknice ojbk 5 oknice ojbk 6 7 8 9 10
-
删除指令
d
删除指定行
-
插入
i
语法和
a
相同,效果是在某一行前面插入。-
输出行
p
-
替换
s/regexp/replacement/[flags]
替换是比较常用的,后面讲。
-
输出行号
=
先输出行号在输出对应行的内容。不在同一行。
[root@localhost sed]# sed -e "=" number.txt 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 10 10
-
字典映射
y
y/src/dst/ # 案例 [root@localhost sed]# sed -e 'y/123456789/abcdefghi/' number.txt a b c d e f g h i a0 # 将src字符翻译成dst字符 src和dst长度应该一致
-
输出结果的内容
l
以类似正则的方式进行输出。数据区的内容,不会有影响。
[root@localhost sed]# sed -n -e 'N;N;p;l' number.txt 1 2 3 1\n2\n3$ 4 5 6 4\n5\n6$ 7 8 9 7\n8\n9$
-
-
指令
s/regexp/replacement/flags
-
这个是常用指令
-
匹配和替换
匹配一行字符串,将匹配的部分用后面的
replacement
进行替换。-
regex
regex
是正则表达式,正则有一般正则和拓展正则。-
匹配组
- 通过括号就可以形成组。将组内数据作为单独的参数,可以单独的获取。
- 在后面的替换可以用
\n
的方式使用。n
的范围是1-9
,&表示匹配的整个字符串。
# 注意强正则和弱正则的区别 [root@localhost sed]# sed -E -e 's/([0-9])/\1\1/' number.txt 11 22 33 44 55 66 77 88 99 110 [root@localhost sed]# sed -e 's/\([0-9]\)/\1\1/' number.txt 11 22 33 44 55 66 77 88 99 110 [root@localhost sed]# sed -E -e "s/(.{5})/-&-/g" alpha.txt -hello--world- -hello--world- [root@localhost sed]# sed -E -e "s/[hw](.{4})/-&-/g" alpha.txt -hello--world- -hello--world- [root@localhost sed]# sed -E -e "s/[hw](.{4})/-\1&-/g" alpha.txt -ellohello--orldworld- -ellohello--orldworld- [root@localhost sed]# sed -E -e "s/[hw](.{4})/-\1|&-/g" alpha.txt -ello|hello--orld|world- -ello|hello--orld|world-
-
界限符号
/
- 这个可以修改,以
s
指令后第一个字符为界限符。包括界限符需要通过反斜杠转义。
[root@localhost sed]# sed -e 's#1#9#' number.txt 9 2 3 4 5 6 7 8 9 90 [root@localhost sed]# sed -e 's;1;9;' number.txt 9 2 3 4 5 6 7 8 9 90 [root@localhost sed]# sed -e 'sa1a9a' number.txt 9 2 3 4 5 6 7 8 9 90
-
替换时大小写转换
-
\L
将符号后面的都转为小写。
lower
-
\l
将符号后面的第一个转换为小写
-
\U
将符号后面的都转为大写。
upper
-
\u
将符号后面的第一个转换为大写
-
\E
停止前面的转换行为。
end
.-
案例
[root@localhost sed]# sed -E -e 's/(.*)/\U\1\E/' alpha.txt HELLOWORLD HELLOWORLD [root@localhost sed]# sed -E -e 's/(.*)/\u\1\E/' alpha.txt Helloworld Helloworld
-
flags
支持的
flag
有很多种-
g
默认是只匹配一个,这个匹配所有。
[root@localhost sed]# sed -E -e 's/(.)/\u\1\E/' alpha.txt Helloworld Helloworld [root@localhost sed]# sed -E -e 's/(.)/\u\1\E/g' alpha.txt HELLOWORLD HELLOWORLD
-
number
只匹配第
n
个。如果和g一起用,则是从n
开始的后面所有。[root@localhost sed]# sed -E -e 's/(.)/\u\1\E/g' alpha.txt HELLOWORLD HELLOWORLD [root@localhost sed]# sed -E -e 's/(.)/\u\1\E/2g' alpha.txt hELLOWORLD hELLOWORLD [root@localhost sed]# sed -E -e 's/(.)/\u\1\E/3g' alpha.txt heLLOWORLD heLLOWORLD
-
输出指定结果
p
将替换后的结果输出。这种指定的声明方式在使用
-n
的时候有用。 -
忽略大小写
I i
加强正则有用
-
多行匹配模式
M m
按行匹配。比如
^ $
,没怎么用。
-
-
补充指令
-
n
按照周期来输出指定行。
[root@localhost sed]# sed -n -e 'n;n;p' number.txt 3 6 9 # 等价于 [root@localhost sed]# sed -n -e '0~3p' number.txt 3 6 9
-
一组指令
使用
{}
将一组命令变为一个指令。[root@localhost sed]# sed -e '1,3{s/1/2/;3d}' number.txt 2 2 4 5 6 7 8 9 10
这种指令只针对某几行。使用和上面的一样。
-
替换指令
c text
这个指令的原发和
i a
相同,效果是替换,按行进行替换。 -
循环指令
指令可以看成顺序的代码。通过
:label
的形式创建一个标签。然后通过
b label,t label
的方式进行跳转。# 会往复执行lable. :lable; commands; b label| t lable;
-
b label
无条件的跳转到
label
位置。-
t label
无条件的跳转,但是如果上一条语句的替换执行成功,则才会进行当前的,如果没有成功则跳过。
while(NULL != readline(data)) { lable: //:lable /* commands */ goto lable; if (end) { exit(0); } }
-
-
检测读取状态
N
在之前的数据的基础上再添加一行。
while(NULL != readline(data)) { {//N; pre_replace_suuceed = readline(data+len(data)+1); if(!data.endswith("\n")) { end = true; } } /* commands */ take_relace(data); //s/\n/L/; if (end) { exit(0); } }
-
处理多行为1行
[root@localhost sed]# sed -e ":lable;N;s/\n/L/;b lable" number.txt 1L2L3L4L5L6L7L8L9L10 [root@localhost sed]# cat number.txt 1 2 3 4 5 6 7 8 9 10
- 等价于
while(NULL != readline(data)) { lable: //:lable {//N; pre_replace_suuceed = readline(data+len(data)+1); if(!data.endswith("\n")) { end = true; } } /* commands */ take_relace(data); //s/\n/L/; goto lable; if (end) { exit(0); } }
-
-
选择行
-
单一行
只处理指定行,1表示第一行,$表示最后一行。注意多个文件的时候,表示整个文件流第一行和最后一行,
-i -s
选项表示每个文件的第一行和最后一行。 -
多行
范围选择
-
正则匹配
处理满足正则的,后面单独讲。
-
周期
first~step
first
表示从哪儿开始。step
表示周期
-
取反
上面的取反。
-
案例
[root@localhost sed]# sed -n -e '1p' number.txt 1 [root@localhost sed]# sed -n -e '1,3p' number.txt 1 2 3 [root@localhost sed]# sed -n -e '/1/p' number.txt 1 10 [root@localhost sed]# sed -n -e '/1/!p' number.txt 2 3 4 5 6 7 8 9 [root@localhost sed]# sed -n -e '3~2p' number.txt 3 5 7 9
-
-
正则选择行
-
说明一般正则和加强正则,典型区分就是需不需要用反斜杠转义。
-
/regexp/
有匹配的列都会算上。正则里面包含了
/
需要通过\
进行声明转义。 -
范围
如果范围前大于后,则只选中一个。
# 选中的行是第一个匹配的行。而且还可以匹配第0行,这里比较特殊。 (/regex/|number),(/regexp/,/number/) # 从 addr1 开始的后面n个 addr1,+N # 从 addr1 开始的周期性的选择。 addr1,~N
-
自定义分隔符
# 所有的都相同。通过转义字符声明自己的分隔符。\character sed -n ’/^\/home\/alice\/documents\//p’ sed -n ’\%^/home/alice/documents/%p’ sed -n ’\;^/home/alice/documents/;p’
-
不分大小写
/regexp/I|\%regexp%I
因为会有小写
i
这个指令。小写表示插入。# 表示匹配b [root@localhost sed]# printf "%s\n" a b c | sed '/b/Id' a c # 匹配的地方前面插入d,a表示后面插入。 [root@localhost sed]# printf "%s\n" a b c | sed '/b/id' a d b c
-
-
来源:oschina
链接:https://my.oschina.net/u/3695598/blog/4310889