Sed命令详解linux
Table of Contents
1. Sed简介
2. 定址
3. Sed命令
4. 选项
5. 元字符集
6. 实例
7. 脚本正则表达式
1. Sed简介算法
sed是一种在线编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,直到文件末尾。文件内容并无 改变,除非你使用重定向存储输出。Sed主要用来自动编辑一个或多个文件;简化对文件的反复操做;编写转换程序等。如下介绍的是Gnu版本的Sed 3.02。
2. 定址shell
能够经过定址来定位你所但愿编辑的行,该地址用数字构成,用逗号分隔的两个行数表示以这两行为起止的行的范围(包括行数表示的那两行)。如1,3表示1,2,3行,美圆符号($)表示最后一行。范围能够经过数据,正则表达式或者两者结合的方式肯定 。express
3. Sed命令apache
调用sed命令有两种形式:跨域
sed [options] 'command' file(s)缓存
sed [options] -f scriptfile file(s)安全
<
a/
在当前行后面加入一行文本。bash
b lable
分支到脚本中带有标记的地方,若是分支不存在则分支到脚本的末尾。
c/
用新的文本改变本行的文本。
d
从模板块(Pattern space)位置删除行。
D
删除模板块的第一行。
i/
在当前行上面插入文本。
h
拷贝模板块的内容到内存中的缓冲区。
H
追加模板块的内容到内存中的缓冲区
g
得到内存缓冲区的内容,并替代当前模板块中的文本。
G
得到内存缓冲区的内容,并追加到当前模板块文本的后面。
l
列表不能打印字符的清单。
n
读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
N
追加下一个输入行到模板块后面并在两者间嵌入一个新行,改变当前行号码。
p
打印模板块的行。
P(大写)
打印模板块的第一行。
q
退出Sed。
r file
从file中读行。
t label
if分支,从最后一行开始,条件一旦知足或者T,t命令,将致使分支到带有标号的命令处,或者到脚本的末尾。
T label
错误分支,从最后一行开始,一旦发生错误或者T,t命令,将致使分支到带有标号的命令处,或者到脚本的末尾。
w file
写并追加模板块到file末尾。
W file
写并追加模板块的第一行到file末尾。
!
表示后面的命令对全部没有被选定的行发生做用。
s/re/string
用string替换正则表达式re。
=
打印当前行号码。
#
把注释扩展到下一个换行符之前。
如下的是替换标记
g表示行内全面替换。
p表示打印行。
w表示把行写入一个文件。
x表示互换模板块中的文本和缓冲区中的文本。
y表示把一个字符翻译为另外的字符(可是不用于正则表达式)
4. 选项
<
-e command, --expression=command
容许多台编辑。
-h, --help
打印帮助,并显示bug列表的地址。
-n, --quiet, --silent
取消默认输出。
-f, --filer=script-file
引导sed脚本文件名。
-V, --version
打印版本和版权信息。
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结尾的单词的行。
x/{m/}
重复字符x,m次,如:/0/{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。
保持和获取: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对于脚本中输入的命令很是挑剔,在命令的末尾不能有任何空白或文本,若是在一行中有多个命令,要用分号分隔。以#开头的行为注释行,且不能跨行。
好比,若是要打印出含有字串”1024”的行,我就可能会用:
cat filename | sed –n ‘/1024/p’sed命令详解!!(要学习shell的 朋友要好好看看)
sed /^$/d filename
能够删除文件中的空行。
sed /^[[:space:]]*$/d filename
能够删除内容为多个空格/tab组成的行。
diff命令详解
总览
描述
在最简单的状况是, diff 比较两个文件的内容 (源文件 和 目标文件). 文件名能够是 - 由标准输入设备读入的文本. 做为特别的状况是, diff - - 比较一份标准输入的它本身的拷贝若是 源文件 是一个目录和 目标文件 不是(目录), diff 会比较在 源文件(目录) 里的文件的中和 目标文件同名的(文件), 反过来也同样. 非目录文件不能是 -. 若是 源文件 和 目标文件 都是目录, diff 比较两个目录中相应的文件,依照字母次序排序;这个比较是不会递归的,除非给出 -r 或者 --recursive. diff 不把一个目录的内容看为它是一个文件来比较。被指定的文件不能是标准的输入, 由于标准的输入是无名的而且"有同样的名字的文件"的观点不适用。 diff 的选项由 -, 开始因此正常地 源文件(名) 和 目标文件(名) 不能够用 - 开头. 然而, -- 能够被它视为保留的即便做为文件名的开头( they begin with -.)
选项
下面是 GNU所接受的 diff 的全部选项的概要. 大多数的选项有两个相同的名字,一个是单个的跟在 - 后面字母, 另外一个是由 -- 引出的长名字. 多个单字母选项(除非它们产生歧义)可以组合为单行的命令行语法 -ac是等同于 -a -c. 长命名的选项能被缩短到他们的名字的任何惟一的前缀. 用 ([ 和 ]) 括起来显示选项产生歧义的选项
-行数(一个整数)
显示上下文 行数 (一个整数). 这个选项自身没有指定输出格式,这是没有效果的,除非和 -c 或者 -u 组合使用. 这是已废置的选项,对于正确的操做, 上下文至少要有两行。
-a
全部的文件都视为文本文件来逐行比较,甚至他们彷佛不是文本文件.
-b
忽略空格引发的变化.
-B
忽略插入删除空行引发的变化.
--brief
仅报告文件是否相异,在意差异的细节.
-c
使用上下文输出格式.
-C 行数(一个整数)
--context[=lines]
使用上下文输出格式,显示以指定 行数 (一个整数), 或者是三行(当 行数 没有给出时. 对于正确的操做, 上下文至少要有两行.
--changed-group-format=format
使用 format 输出一组包含两个文件的不一样处的行,其格式是 if-then-else .
-d
改变算法也许发现变化的一个更小的集合.这会使 diff 变慢 (有时更慢).
-D name
合并 if-then-else 格式输出, 预处理宏(由name参数提供)条件.
-e
--ed
输出为一个有效的 ed 脚本.
--exclude=pattern
比较目录的时候,忽略和目录中与 pattern(样式) 相配的.
--exclude-from=file
比较目录的时候,忽略和目录中与任何包含在 file(文件) 的样式相配的文件和目录.
--expand-tabs
在输出时扩展tab为空格,保护输入文件的tab对齐方式
-f
产生一个很象 ed 脚本的输出,可是可是在他们在文件出现的顺序有改变
-F regexp
在上下文和统一格式中,对于每一大块的不一样,显示出匹配 regexp. 的一些前面的行.
--forward-ed
产生象 ed 脚本的输出,可是它们在文件出现的顺序有改变。
-h
这选项如今已没做用,它呈现Unix的兼容性.
-H
使用启发规则加速操做那些有许多离散的小差别的大文件.
--horizon-lines=lines
比较给定行数的有共同前缀的最后行,和有共同或缀的最前行.
-i
忽略大小写.
-I regexp
忽略由插入,删除行(由regexp 参数提供参考)带来的改变.
--ifdef=name
合并 if-then-else 格式输出, 预处理宏(由name参数提供)条件.
--ignore-all-space
在比较行的时候忽略空白.
--ignore-blank-lines
忽略插入和删除空行
--ignore-case
忽略大小写.
--ignore-matching-lines=regexp
忽略插入删除行(由regexp 参数提供参考).
--ignore-space-change
忽略空白的数量.
--initial-tab
在文本行(不管是常规的或者格式化的先后文关系)前输出tab代替空格. 引发的缘由是tab对齐方式看上去象是常规的同样.
-l
产生经过 pr 编码的输出.
-L label
--label=label
使用 label 给出的字符在文件头代替文件名输出.
--left-column
以并列方式印出两公共行的左边
--line-format=format
使用 format 输出全部的行,在 if-then-else 格式中.
--minimal
改变算法也许发现变化的一个更小的集合.这会使 diff 变慢 (有时更慢).
-n
输出 RC-格式 diffs; 除了每条指令指定的行数受影响外 象 -f 同样。
-N
--new-file
在目录比较中,若是那个文件只在其中的一个目录中找到,那么它被视为在另外一个目录中是一个空文件.
--new-group-format=format
使用 format 以if-then-else 格式输出只在第二个文件中取出的一个行组
--new-line-format=format
使用 format 以if-then-else 格式输出只在第二个文件中取出的一行
--old-group-format=format
使用 format 以if-then-else 格式输出只在第一个文件中取出的一个行组
--old-line-format=format
使用 format 使用 format 以if-then-else 格式输出只在第一个文件中取出的一行
-p
显示带有c函数的改变.
-P
在目录比较中,若是那个文件只在其中的一个目录中找到,那么它被视为在另外一个目录中是一个空文件.
--paginate
产生经过 pr 编码的输出.
-q
仅报告文件是否相异,不报告详细的差别.
-r
当比较目录时,递归比较任何找到的子目录.
--rcs
输出 RC-格式 diffs; 除了每条指令指定的行数受影响外 象 -f 同样。
--recursive
当比较目录时,递归比较任何找到的子目录.
--report-identical-files
-s
报告两个文件相同.
-S file
当比较目录时,由 file 开始. 这用于继续中断了的比较.
--sdiff-merge-assist
打印附加的信息去帮助 sdiff. sdiff 在运行 diff 时使用这些选项. 这些选项不是特地为使用者直接使用而准备的。
--show-c-function
显示带有c函数的改变.
--show-function-line=regexp
在上下文和统一的格式,对于每一大块的差异,显示出匹配 regexp. 的一些前面的行
--side-by-side
使用并列的输出格式.
--speed-large-files
使用启发规则加速操做那些有许多离散的小差别的大文件.
--starting-file=file
当比较目录时,由 file 开始. 这用于继续中断了的比较.
--suppress-common-lines
在并列格式中不印出公共行。
-t
在输出时扩展tab为空格,保护输入文件的tab对齐方式
-T
在文本行(不管是常规的或者格式化的先后文关系)前输出tab代替空格.引发的缘由是tab对齐方式看上去象是常规的同样.
--text
全部的文件都视为文本文件来逐行比较,甚至他们彷佛不是文本文件.
-u
使用统一的输出格式.
--unchanged-group-format=format
使用 format 输出两个文件的公共行组,其格式是if-then-else.
--unchanged-line-format=format
使用 format 输出两个文件的公共行,其格式是if-then-else.
--unidirectional-new-file
在目录比较中,若是那个文件只在其中的一个目录中找到,那么它被视为在另外一个目录中是一个空文件.
-U lines
--unified[=lines]
使用先后关系格式输出,显示以指定 行数 (一个整数), 或者是三行(当 行数 没有给出时. 对于正确的操做, 上下文至少要有两行.
-v
--version
输出 diff 版本号.
-w
在比较行时忽略空格
-W columns
--width=columns
在并列格式输出时,使用指定的列宽.
-x pattern
比较目录的时候,忽略和目录中与 pattern(样式) 相配的.
-X file
比较目录的时候,忽略和目录中与任何包含在 file(文件) 的样式相配的文件和目录.
-y
使用并列格式输出
实例:有这样两个文件:程序清单1 :hello.c#include
int main(void)
{
char msg[] = "Hello world!";
puts(msg);
printf("Welcome to use diff commond.\n");
return 0;
}程序清单2:hello_diff.c#include
#include
int main(void)
{
char msg[] = "Hello world,fome hello_diff.c";
puts(msg);
printf("hello_diff.c says,'Here you are,using diff.'\n");
return 0;
}咱们使用diff命令来查看这两个文件的不一样之处,有一下几种方便的方法:
1、普通格式输出:[root@localhost diff]# diff hello.c hello_diff.c
1a2
> #include
5c6
char msg[] = "Hello world,fome hello_diff.c";
8c9
printf("hello_diff.c says,'Here you are,using diff.'\n");
[root@localhost diff]# 上面的“1a2”表示后面的一个文件"hello_diff.c"比前面的一个文件"hello.c"多了一行
"5c6"表示第一个文件的第5行与第二个文件的第6行有区别
2、并排格式输出[root@localhost diff]# diff hello.c hello_diff.c -y -W 130
#include #include
> #include
int main(void) int main(void)
{ {
char msg[] = "Hello world!"; | char msg[] = "Hello world,fome hello_diff.c";
puts(msg); puts(msg);
printf("Welcome to use diff commond.\n"); | printf("hello_diff.c says,'Here you are,using diff.'\
return 0; return 0;
} }
[root@localhost diff]# 这种并排格式的对比一目了然,能够快速找到不一样的地方。
-W选择能够指定输出列的宽度,这里指定输出列宽为130
3、上下文输出格式[root@localhost diff]# diff hello.c hello_diff.c -c
*** hello.c 2007-09-25 17:54:51.000000000 +0800
--- hello_diff.c 2007-09-25 17:56:00.000000000 +0800
***************
*** 1,11 ****
#include
int main(void)
{
! char msg[] = "Hello world!";
puts(msg);
! printf("Welcome to use diff commond.\n");
return 0;
}
--- 1,12 ----
#include
+ #include
int main(void)
{
! char msg[] = "Hello world,fome hello_diff.c";
puts(msg);
! printf("hello_diff.c says,'Here you are,using diff.'\n");
return 0;
}
[root@localhost diff]# 这种方式在开头两行做了比较文件的说明,这里有三中特殊字符:+ 比较的文件的后者比前着多一行- 比较的文件的后者比前着少一行 ! 比较的文件二者有差异的行
4、统一输出格式[root@localhost diff]# diff hello.c hello_diff.c -u
--- hello.c 2007-09-25 17:54:51.000000000 +0800
+++ hello_diff.c 2007-09-25 17:56:00.000000000 +0800
@@ -1,11 +1,12 @@
#include
+#include
int main(void)
{
- char msg[] = "Hello world!";
+ char msg[] = "Hello world,fome hello_diff.c";
puts(msg);
- printf("Welcome to use diff commond.\n");
+ printf("hello_diff.c says,'Here you are,using diff.'\n");
return 0;
}
[root@localhost diff]# 正如看到的那样,统一格式的输出更加紧凑,因此更易于理解,更易于修改。
5、其余假如你想查看两个文件是否不一样又不想显示差别之处的话,能够加上-q选项:[root@localhost diff]# diff hello.c hello_diff.c -q
Files hello.c and hello_diff.c differ
[root@localhost diff]# 另外你还能够提供一些匹配规则来忽略某中差异,能够用 -I regexp[root@localhost diff]# diff hello.c hello_diff.c -c -I include
*** hello.c 2007-09-25 17:54:51.000000000 +0800
--- hello_diff.c 2007-09-25 17:56:00.000000000 +0800
***************
*** 2,11 ****
int main(void)
{
! char msg[] = "Hello world!";
puts(msg);
! printf("Welcome to use diff commond.\n");
return 0;
}
--- 3,12 ----
int main(void)
{
! char msg[] = "Hello world,fome hello_diff.c";
puts(msg);
! printf("hello_diff.c says,'Here you are,using diff.'\n");
return 0;
}
[root@localhost diff]# 这里经过“ -I include”选项来忽略带有“ include”字样的行
Sort命令详解
sort是在Linux里很是经常使用的一个命令,管排序的,集中精力,五分钟搞定sort,如今开始!
1 sort的工做原理
sort将文件的每一行做为一个单位,相互比较,比较原则是从首字符向后,依次按ASCII码值进行比较,最后将他们按升序输出。
[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
2 sort的-u选项
它的做用很简单,就是在输出行中去除重复行。
[rocrocket@rocrocket programming]$ cat seq.txt
banana
apple
pear
orange
pear
[rocrocket@rocrocket programming]$ sort seq.txt
apple
banana
orange
pear
pear
[rocrocket@rocrocket programming]$ sort -u seq.txt
apple
banana
orange
pear
pear因为重复被-u选项无情的删除了。
3 sort的-r选项
sort默认的排序方式是升序,若是想改为降序,就加个-r就搞定了。
[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort number.txt
1
2
3
4
5
[rocrocket@rocrocket programming]$ sort -r number.txt
5
4
3
2
1
4 sort的-o选项
因为sort默认是把结果输出到标准输出,因此须要用重定向才能将结果写入文件,形如sort filename > newfile。
可是,若是你想把排序结果输出到原文件中,用重定向可就不行了。
[rocrocket@rocrocket programming]$ sort -r number.txt > number.txt
[rocrocket@rocrocket programming]$ cat number.txt
[rocrocket@rocrocket programming]$
看,居然将number清空了。
就在这个时候,-o选项出现了,它成功的解决了这个问题,让你放心的将结果写入原文件。这或许也是-o比重定向的惟一优点所在。
[rocrocket@rocrocket programming]$ cat number.txt
1
3
5
2
4
[rocrocket@rocrocket programming]$ sort -r number.txt -o number.txt
[rocrocket@rocrocket programming]$ cat number.txt
5
4
3
2
1
5 sort的-n选项
你有没有遇到过10比2小的状况。我反正遇到过。出现这种状况是因为排序程序将这些数字按字符来排序了,排序程序会先比较1和2,显然1小,因此就将10放在2前面喽。这也是sort的一向做风。
咱们若是想改变这种现状,就要使用-n选项,来告诉sort,“要以数值来排序”!
[rocrocket@rocrocket programming]$ cat number.txt
1
10
19
11
2
5
[rocrocket@rocrocket programming]$ sort number.txt
1
10
11
19
2
5
[rocrocket@rocrocket programming]$ sort -n number.txt
1
2
5
10
11
19
6 sort的-t选项和-k选项
若是有一个文件的内容是这样:
[rocrocket@rocrocket programming]$ cat facebook.txt
banana:30:5.5
apple:10:2.5
pear:90:2.3
orange:20:3.4
这个文件有三列,列与列之间用冒号隔开了,第一列表示水果类型,第二列表示水果数量,第三列表示水果价格。
那么我想以水果数量来排序,也就是以第二列来排序,如何利用sort实现?
幸亏,sort提供了-t选项,后面能够设定间隔符。(是否是想起了cut和paste的-d选项,共鸣~~)
指定了间隔符以后,就能够用-k来指定列数了。
[rocrocket@rocrocket programming]$ sort -n -k 2 -t : facebook.txt
apple:10:2.5
orange:20:3.4
banana:30:5.5
pear:90:2.3
咱们使用冒号做为间隔符,并针对第二列来进行数值升序排序,结果很使人满意。
7 其余的sort经常使用选项
-f会将小写字母都转换为大写字母来进行比较,亦即忽略大小写
-c会检查文件是否已排好序,若是乱序,则输出第一个乱序的行的相关信息,最后返回1
-C会检查文件是否已排好序,若是乱序,不输出内容,仅返回1
-M会以月份来排序,好比JAN小于FEB等等
-b会忽略每一行前面的全部空白部分,从第一个可见字符开始比较。
有时候学习脚本,你会发现sort命令后面跟了一堆相似-k1,2,或者-k1.2 -k3.4的东东,有些匪夷所思。今天,咱们就来搞定它—-k选项!
1 准备素材
$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
第一个域是公司名称,第二个域是公司人数,第三个域是员工平均工资。(除了公司名称,其余的别信,都瞎写的^_^)
2 我想让这个文件按公司的字母顺序排序,也就是按第一个域进行排序:(这个facebook.txt文件有三个域)
$ sort -t ‘ ‘ -k 1 facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
看到了吧,就直接用-k 1设定就能够了。(其实此处并不严格,稍后你就会知道)
3 我想让facebook.txt按照公司人数排序
$ sort -n -t ‘ ‘ -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
不用解释,我相信你能懂。
可是,此处出现了问题,那就是baidu和sohu的公司人数相同,都是100人,这个时候怎么办呢?按照默认规矩,是从第一个域开始进行升序排序,所以baidu排在了sohu前面。
4 我想让facebook.txt按照公司人数排序 ,人数相同的按照员工平均工资升序排序:
$ sort -n -t ‘ ‘ -k 2 -k 3 facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
看,咱们加了一个-k2 -k3就解决了问题。对滴,sort支持这种设定,就是说设定域排序的优先级,先以第2个域进行排序,若是相同,再以第3个域进行排序。(若是你愿意,能够一直这么写下去,设定不少个排序优先级)
5 我想让facebook.txt按照员工工资降序排序,若是员工人数相同的,则按照公司人数升序排序:(这个有点难度喽)
$ sort -n -t ‘ ‘ -k 3r -k 2 facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
此处有使用了一些小技巧,你仔细看看,在-k 3后面偷偷加上了一个小写字母r。你想一想,再结合咱们上一篇文章,能获得答案么?揭晓:r和-r选项的做用是同样的,就是表示逆序。由于sort默认是按照升序排序的,因此此处须要加上r表示第三个域(员工平均工资)是按照降序排序。此处你还能够加上n,就表示对这个域进行排序时,要按照数值大小进行排序,举个例子吧:
$ sort -t ‘ ‘ -k 3nr -k 2n facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
看,咱们去掉了最前面的-n选项,而是将它加入到了每个-k选项中了。
6 -k选项的具体语法格式
要继续往下深刻的话,就不得不来点理论知识。你须要了解-k选项的语法格式,以下:
[ FStart [ .CStart ] ] [ Modifier ] [ , [ FEnd [ .CEnd ] ][ Modifier ] ]
这个语法格式能够被其中的逗号(“,”)分为两大部分,Start部分和End部分。
先给你灌输一个思想,那就是“若是不设定End部分,那么就认为End被设定为行尾”。这个概念很重要的,但每每你不会重视它。
Start部分也由三部分组成,其中的Modifier部分就是咱们以前说过的相似n和r的选项部分。咱们重点说说Start部分的FStart和C.Start。
C.Start也是能够省略的,省略的话就表示从本域的开头部分开始。以前例子中的-k 2和-k 3就是省略了C.Start的例子喽。
FStart.CStart,其中FStart就是表示使用的域,而CStart则表示在FStart域中从第几个字符开始算“排序首字符”。
同理,在End部分中,你能够设定FEnd.CEnd,若是你省略.CEnd,则表示结尾到“域尾”,即本域的最后一个字符。或者,若是你将CEnd设定为0(零),也是表示结尾到“域尾”。
7 突发奇想,从公司英文名称的第二个字母开始进行排序:
$ sort -t ‘ ‘ -k 1.2 facebook.txt
baidu 100 5000
sohu 100 4500
google 110 5000
guge 50 3000
看,咱们使用了-k 1.2,这就表示对第一个域的第二个字符开始到本域的最后一个字符为止的字符串进行排序。你会发现baidu由于第二个字母是a而名列榜首。sohu和 google第二个字符都是o,但sohu的h在google的o前面,因此二者分别排在第二和第三。guge只能屈居第四了。
8 又突发奇想,,只针对公司英文名称的第二个字母进行排序,若是相同的按照员工工资进行降序排序:
$ sort -t ‘ ‘ -k 1.2,1.2 -k 3,3nr facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
guge 50 3000
因为只对第二个字母进行排序,因此咱们使用了-k 1.2,1.2的表示方式,表示咱们“只”对第二个字母进行排序。(若是你问“我使用-k 1.2怎么不行?”,固然不行,由于你省略了End部分,这就意味着你将对从第二个字母起到本域最后一个字符为止的字符串进行排序)。对于员工工资进行排 序,咱们也使用了-k 3,3,这是最准确的表述,表示咱们“只”对本域进行排序,由于若是你省略了后面的3,就变成了咱们“对第3个域开始到最后一个域位置的内容进行排序” 了。
9 在modifier部分还能够用到哪些选项?
能够用到b、d、f、i、n 或 r。
其中n和r你确定已经很熟悉了。
b表示忽略本域的签到空白符号。
d表示对本域按照字典顺序排序(即,只考虑空白和字母)。
f表示对本域忽略大小写进行排序。
i表示忽略“不可打印字符”,只针对可打印字符进行排序。(有些ASCII就是不可打印字符,好比\a是报警,\b是退格,\n是换行,\r是回车等等)
10 思考思考关于-k和-u联合使用的例子:
$ cat facebook.txt
google 110 5000
baidu 100 5000
guge 50 3000
sohu 100 4500
这是最原始的facebook.txt文件。
$ sort -n -k 2 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
$ sort -n -k 2 -u facebook.txt
guge 50 3000
baidu 100 5000
google 110 5000
当设定以公司员工域进行数值排序,而后加-u后,sohu一行就被删除了!原来-u只识别用-k设定的域,发现相同,就将后续相同的行都删除。
$ sort -k 1 -u facebook.txt
baidu 100 5000
google 110 5000
guge 50 3000
sohu 100 4500
$ sort -k 1.1,1.1 -u facebook.txt
baidu 100 5000
google 110 5000
sohu 100 4500
这个例子也同理,开头字符是g的guge就没有幸免于难。
$ sort -n -k 2 -k 3 -u facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
google 110 5000
咦!这里设置了两层排序优先级的状况下,使用-u就没有删除任何行。原来-u是会权衡全部-k选项,将都相同的才会删除,只要其中有一级不一样都不会轻易删除的:)(不信,你能够本身加一行sina 100 4500试试看)
11 最诡异的排序:
$ sort -n -k 2.2,3.1 facebook.txt
guge 50 3000
baidu 100 5000
sohu 100 4500
google 110 5000
以第二个域的第二个字符开始到第三个域的第一个字符结束的部分进行排序。
第一行,会提取0 3,第二行提取00 5,第三行提取00 4,第四行提取10 5。
又由于sort认为0小于00小于000小于0000….
所以0 3确定是在第一个。10 5确定是在最后一个。但为何00 5却在00 4前面呢?(你能够本身作实验思考一下。)
答案揭晓:原来“跨域的设定是个假象”,sort只会比较第二个域的第二个字符到第二个域的最后一个字符的部分,而不会把第三个域的开头字符归入比较范围。当发现00和00相同时,sort就会自动比较第一个域去了。固然baidu在sohu前面了。用一个范例便可证明:
$ sort -n -k 2.2,3.1 -k 1,1r facebook.txt
guge 50 3000
sohu 100 4500
baidu 100 5000
shell中wc命令详解
shell中wc命令详解
wc命令的功能为统计指定文件中的字节数、字数、行数, 并将统计结果显示输出。
语法:wc [选项] 文件…
说明:该命令统计给定文件中的字节数、字数、行数。若是没有给出文件名,则从标准输入读取。wc同时也给出全部指定文件的总统计数。字是由空格字符区分开的最大字符串。
该命令各选项含义以下:
- c 统计字节数。
- l 统计行数。
- w 统计字数。
这些选项能够组合使用。
输出列的顺序和数目不受选项的顺序和数目的影响。老是按下述顺序显示而且每项最多一列。
行数、字数、字节数、文件名
若是命令行中没有文件名,则输出中不出现文件名。
例如:
$ wc - lcw file1 file2
4 33 file1
7 52 file2
11 11 85 total
省略任选项-lcw,wc命令的执行结果与上面同样。
Find命令详解
1、find命令的通常形式为;
find pathname -options [-print -exec -ok ...]
2、find命令的参数;
· pathname: find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录。
· -print: find命令将匹配的文件输出到标准输出。
· -exec: find命令对匹配的文件执行该参数所给出的shell命令。相应命令的形式为"command { } \; ",注意"{ }"和“\;”之间的空格。
· -ok: 和-exec的做用相同,只不过以一种更为安全的模式来执行该参数所给出的shell命令,在执行每个命令以前,都会给出提示,让用户来肯定是否执行。
3、find命令选项
-name 按照文件名查找文件。
-perm 按照文件权限来查找文件。
-prune 使用这一选项可使find命令不在当前指定的目录中查找,若是同时使用-depth选项,那么-prune将被find命令忽略。
-user 按照文件属主来查找文件。
-group 按照文件所属的组来查找文件。
-mtime -n +n 按照文件的更改时间来查找文件, - n表示文件更改时间距如今n天之内,+ n表示文件更改时间距如今n天之前。find命令还有-atime和-ctime 选项,但它们都和-m time选项。
-nogroup 查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。
-nouser 查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。
-newer file1 ! file2 查找更改时间比文件file1新但比文件file2旧的文件。
-type 查找某一类型的文件,诸如:b - 块设备文件。d - 目录。c - 字符设备文件。p - 管道文件。l - 符号连接文件。f - 普通文件。
-size n:[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。
-depth:在查找文件时,首先查找当前目录中的文件,而后再在其子目录中查找。
-fstype:查找位于某一类型文件系统中的文件,这些文件系统类型一般能够在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。
-mount:在查找文件时不跨越文件系统mount点。
-follow:若是find命令遇到符号连接文件,就跟踪至连接所指向的文件。
-cpio:对匹配的文件使用cpio命令,将这些文件备份到磁带设备中。
另外,下面三个的区别:
-amin n 查找系统中最后N分钟访问的文件
-atime n 查找系统中最后n*24小时访问的文件
-cmin n 查找系统中最后N分钟被改变文件状态的文件
-ctime n 查找系统中最后n*24小时被改变文件状态的文件
-mmin n 查找系统中最后N分钟被改变文件数据的文件
-mtime n 查找系统中最后n*24小时被改变文件数据的文件
4、使用exec或ok来执行shell命令
使用find时,只要把想要的操做写在一个文件里,就能够用exec来配合find查找,很方便的
在有些操做系统中只容许-exec选项执行诸如l s或ls -l这样的命令。大多数用户使用这一选项是为了查找旧文件并删除它们。建议在真正执行rm命令删除文件以前,最好先用ls命令看一下,确认它们是所要删除的文件。
exec选项后面跟随着所要执行的命令或脚本,而后是一对儿{ },一个空格和一个\,最后是一个分号。为了使用exec选项,必需要同时使用print选项。若是验证一下find命令,会发现该命令只输出从当前路径起的相对路径及文件名。
例如:为了用ls -l命令列出所匹配到的文件,能够把ls -l命令放在find命令的-exec选项中
# find . -type f -exec ls -l { } \;
-rw-r--r-- 1 root root 34928 2003-02-25 ./conf/httpd.conf
-rw-r--r-- 1 root root 12959 2003-02-25 ./conf/magic
-rw-r--r-- 1 root root 180 2003-02-25 ./conf.d/README
上面的例子中,find命令匹配到了当前目录下的全部普通文件,并在-exec选项中使用ls -l命令将它们列出。
在/logs目录中查找更改时间在5日之前的文件并删除它们:
$ find logs -type f -mtime +5 -exec rm { } \;
记住:在shell中用任何方式删除文件以前,应当先查看相应的文件,必定要当心!当使用诸如mv或rm命令时,可使用-exec选项的安全模式。它将在对每一个匹配到的文件进行操做以前提示你。
在下面的例子中, find命令在当前目录中查找全部文件名以.LOG结尾、更改时间在5日以上的文件,并删除它们,只不过在删除以前先给出提示。
$ find . -name "*.conf" -mtime +5 -ok rm { } \;
< rm ... ./conf/httpd.conf > ? n
按y键删除文件,按n键不删除。
任何形式的命令均可以在-exec选项中使用。
在下面的例子中咱们使用grep命令。find命令首先匹配全部文件名为“ passwd*”的文件,例如passwd、passwd.old、passwd.bak,而后执行grep命令看看在这些文件中是否存在一个sam用户。
# find /etc -name "passwd*" -exec grep "sam" { } \;
sam:x:501:501::/usr/sam:/bin/bash
2、find命令的例子;
1、查找当前用户主目录下的全部文件:下面两种方法均可以使用
$ find $HOME -print
$ find ~ -print
2、让当前目录中文件属主具备读、写权限,而且文件所属组的用户和其余用户具备读权限的文件;
$ find . -type f -perm 644 -exec ls -l { } \;
3、为了查找系统中全部文件长度为0的普通文件,并列出它们的完整路径;
$ find / -type f -size 0 -exec ls -l { } \;
4、查找/var/logs目录中更改时间在7日之前的普通文件,并在删除以前询问它们;
$ find /var/logs -type f -mtime +7 -ok rm { } \;
5、为了查找系统中全部属于root组的文件;
$find . -group root -exec ls -l { } \;
-rw-r--r-- 1 root root 595 10月 31 01:09 ./fie1
6、find命令将删除当目录中访问时间在7日以来、含有数字后缀的admin.log文件。
该命令只检查三位数字,因此相应文件的后缀不要超过999。先建几个admin.log*的文件 ,才能使用下面这个命令
$ find . -name "admin.log[0-9][0-9][0-9]" -atime -7 -ok
rm { } \;
< rm ... ./admin.log001 > ? n
< rm ... ./admin.log002 > ? n
< rm ... ./admin.log042 > ? n
< rm ... ./admin.log942 > ? n
7、为了查找当前文件系统中的全部目录并排序;
$ find . -type d | sort
8、为了查找系统中全部的rmt磁带设备;
$ find /dev/rmt -print
3、find 命令的参数
下面是find一些经常使用参数的例子,有用到的时候查查就好了,像上面前几个贴子,都用到了其中的的一些参数,也能够用man或查看论坛里其它贴子有find的命令手册
1、使用name选项
文件名选项是find命令最经常使用的选项,要么单独使用该选项,要么和其余选项一块儿使用。
可使用某种文件名模式来匹配文件,记住要用引号将文件名模式引发来。
无论当前路径是什么,若是想要在本身的根目录$HOME中查找文件名符合*.txt的文件,使用~做为 'pathname'参数,波浪号~表明了你的$HOME目录。
$ find ~ -name "*.txt" -print
想要在当前目录及子目录中查找全部的‘ *.txt’文件,能够用:
$ find . -name "*.txt" -print
想要的当前目录及子目录中查找文件名以一个大写字母开头的文件,能够用:
$ find . -name "[A-Z]*" -print
想要在/etc目录中查找文件名以host开头的文件,能够用:
$ find /etc -name "host*" -print
想要查找$HOME目录中的文件,能够用:
$ find ~ -name "*" -print 或find . -print
要想让系统高负荷运行,就从根目录开始查找全部的文件。
$ find / -name "*" -print
若是想在当前目录查找文件名以两个小写字母开头,跟着是两个数字,最后是.txt的文件,下面的命令就可以返回名为ax37.txt的文件:
$find . -name "[a-z][a-z][0--9][0--9].txt" -print
2、用perm选项
按照文件权限模式用-perm选项,按文件权限模式来查找文件的话。最好使用八进制的权限表示法。
如在当前目录下查找文件权限位为755的文件,即文件属主能够读、写、执行,其余用户能够读、执行的文件,能够用:
$ find . -perm 755 -print
还有一种表达方法:在八进制数字前面要加一个横杠-,表示都匹配,如-007就至关于777,-006至关于666
# ls -l
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 http3.conf
-rw-rw-rw- 1 sam adm 34890 10月 31 00:57 httpd1.conf
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf
drw-rw-rw- 2 gem group 4096 10月 26 19:48 sam
-rw-rw-rw- 1 root root 2792 10月 31 20:19 temp
# find . -perm 006
# find . -perm -006
./sam
./httpd1.conf
./temp
-perm mode:文件许可正好符合mode
-perm +mode:文件许可部分符合mode
-perm -mode: 文件许可彻底符合mode
3、忽略某个目录
若是在查找文件时但愿忽略某个目录,由于你知道那个目录中没有你所要查找的文件,那么可使用-prune选项来指出须要忽略的目录。在使用-prune选项时要小心,由于若是你同时使用了-depth选项,那么-prune选项就会被find命令忽略。
若是但愿在/apps目录下查找文件,但不但愿在/apps/bin目录下查找,能够用:
$ find /apps -path "/apps/bin" -prune -o -print
4、使用find查找文件的时候怎么避开某个文件目录
好比要在/usr/sam目录下查找不在dir1子目录以内的全部文件
find /usr/sam -path "/usr/sam/dir1" -prune -o -print
find [-path ..] [expression] 在路径列表的后面的是表达式
-path "/usr/sam" -prune -o -print 是 -path "/usr/sam" -a -prune -o
-print 的简写表达式按顺序求值, -a 和 -o 都是短路求值,与 shell 的 && 和 || 相似若是 -path "/usr/sam" 为真,则求值 -prune , -prune 返回真,与逻辑表达式为真;不然不求值 -prune,与逻辑表达式为假。若是 -path "/usr/sam" -a -prune 为假,则求值 -print ,-print返回真,或逻辑表达式为真;不然不求值 -print,或逻辑表达式为真。
这个表达式组合特例能够用伪码写为
if -path "/usr/sam" then
-prune
else
避开多个文件夹
find /usr/sam \( -path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -print
圆括号表示表达式的结合。
\ 表示引用,即指示 shell 不对后面的字符做特殊解释,而留给 find 命令去解释其意义。
查找某一肯定文件,-name等选项加在-o 以后
#find /usr/sam \(-path /usr/sam/dir1 -o -path /usr/sam/file1 \) -prune -o -name "temp" -print
5、使用user和nouser选项
按文件属主查找文件,如在$HOME目录中查找文件属主为sam的文件,能够用:
$ find ~ -user sam -print
在/etc目录下查找文件属主为uucp的文件:
$ find /etc -user uucp -print
为了查找属主账户已经被删除的文件,可使用-nouser选项。这样就可以找到那些属主在/etc/passwd文件中没有有效账户的文件。在使用-nouser选项时,没必要给出用户名; find命令可以为你完成相应的工做。
例如,但愿在/home目录下查找全部的这类文件,能够用:
$ find /home -nouser -print
6、使用group和nogroup选项
就像user和nouser选项同样,针对文件所属于的用户组, find命令也具备一样的选项,为了在/apps目录下查找属于gem用户组的文件,能够用:
$ find /apps -group gem -print
要查找没有有效所属用户组的全部文件,可使用nogroup选项。下面的find命令从文件系统的根目录处查找这样的文件
$ find / -nogroup-print
7、按照更改时间或访问时间等查找文件
若是但愿按照更改时间来查找文件,可使用mtime,atime或ctime选项。若是系统忽然没有可用空间了,颇有可能某一个文件的长度在此期间增加迅速,这时就能够用mtime选项来查找这样的文件。
用减号-来限定更改时间在距今n日之内的文件,而用加号+来限定更改时间在距今n日之前的文件。
但愿在系统根目录下查找更改时间在5日之内的文件,能够用:
$ find / -mtime -5 -print
为了在/var/adm目录下查找更改时间在3日之前的文件,能够用:
$ find /var/adm -mtime +3 -print
8、查找比某个文件新或旧的文件
若是但愿查找更改时间比某个文件新但比另外一个文件旧的全部文件,可使用-newer选项。它的通常形式为:
newest_file_name ! oldest_file_name
其中,!是逻辑非符号。
查找更改时间比文件sam新但比文件temp旧的文件:
例:有两个文件
-rw-r--r-- 1 sam adm 0 10月 31 01:07 fiel
-rw-rw-rw- 1 sam adm 34890 10月 31 00:57 httpd1.conf
-rwxrwxr-x 2 sam adm 0 10月 31 01:01 httpd.conf
drw-rw-rw- 2 gem group 4096 10月 26 19:48 sam
-rw-rw-rw- 1 root root 2792 10月 31 20:19 temp
# find -newer httpd1.conf ! -newer temp -ls
1077669 0 -rwxrwxr-x 2 sam adm 0 10月 31 01:01 ./httpd.conf
1077671 4 -rw-rw-rw- 1 root root 2792 10月 31 20:19 ./temp
1077673 0 -rw-r--r-- 1 sam adm 0 10月 31 01:07 ./fiel
查找更改时间在比temp文件新的文件:
$ find . -newer temp -print
9、使用type选项
在/etc目录下查找全部的目录,能够用:
$ find /etc -type d -print
在当前目录下查找除目录之外的全部类型的文件,能够用:
$ find . ! -type d -print
在/etc目录下查找全部的符号连接文件,能够用
$ find /etc -type l -print
10、使用size选项
能够按照文件长度来查找文件,这里所指的文件长度既能够用块(block)来计量,也能够用字节来计量。以字节计量文件长度的表达形式为N c;以块计量文件长度只用数字表示便可。
在按照文件长度查找文件时,通常使用这种以字节表示的文件长度,在查看文件系统的大小,由于这时使用块来计量更容易转换。
在当前目录下查找文件长度大于1 M字节的文件:
$ find . -size +1000000c -print
在/home/apache目录下查找文件长度刚好为100字节的文件:
$ find /home/apache -size 100c -print
在当前目录下查找长度超过10块的文件(一块等于512字节):
$ find . -size +10 -print
11、使用depth选项
在使用find命令时,可能但愿先匹配全部的文件,再在子目录中查找。使用depth选项就可使find命令这样作。这样作的一个缘由就是,当在使用find命令向磁带上备份文件系统时,但愿首先备份全部的文件,其次再备份子目录中的文件。
在下面的例子中, find命令从文件系统的根目录开始,查找一个名为CON.FILE的文件。
它将首先匹配全部的文件而后再进入子目录中查找。
$ find / -name "CON.FILE" -depth -print
cut是一个选取命令,就是将一段数据通过分析,取出咱们想要的。通常来讲,选取信息一般是针对“行”来进行分析的,并非整篇信息分析的。
(1)其语法格式为:
cut [-bn] [file] 或 cut [-c] [file] 或 cut [-df] [file]
使用说明
cut 命令从文件的每一行剪切字节、字符和字段并将这些字节、字符和字段写至标准输出。
若是不指定 File 参数,cut 命令将读取标准输入。必须指定 -b、-c 或 -f 标志之一。
主要参数
-b :以字节为单位进行分割。这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志。
-c :以字符为单位进行分割。
-d :自定义分隔符,默认为制表符。
-f :与-d一块儿使用,指定显示哪一个区域。
-n :取消分割多字节字符。仅和 -b 标志一块儿使用。若是字符的最后一个字节落在由 -b 标志的 List 参数指示的<br />范围以内,该字符将被写出;不然,该字符将被排除。
(2)cut通常以什么为依据呢? 也就是说,我怎么告诉cut我想定位到的剪切内容呢?
cut命令主要是接受三个定位方法:
第一,字节(bytes),用选项-b
第二,字符(characters),用选项-c
第三,域(fields),用选项-f
(3)以“字节”定位
举个例子吧,当你执行ps命令时,会输出相似以下的内容:
[rocrocket@rocrocket programming]$ who
rocrocket :0 2009-01-08 11:07
rocrocket pts/0 2009-01-08 11:23 (:0.0)
rocrocket pts/1 2009-01-08 14:15 (:0.0)
若是咱们想提取每一行的第3个字节,就这样:
[rocrocket@rocrocket programming]$ who|cut -b 3
c
c
c
(4) 若是“字节”定位中,我想提取第3,第4、第5和第8个字节,怎么办?
-b支持形如3-5的写法,并且多个定位之间用逗号隔开就成了。看看例子吧:
[rocrocket@rocrocket programming]$ who|cut -b 3-5,8
croe
croe
croe
但有一点要注意,cut命令若是使用了-b选项,那么执行此命令时,cut会先把-b后面全部的定位进行从小到大排序,而后再提取。可不能颠倒定位的顺序哦。这个例子就能够说明这个问题:
[rocrocket@rocrocket programming]$ who|cut -b 8,3-5
croe
croe
croe
(5) 还有哪些相似“3-5”这样的小技巧,列举一下吧!
[rocrocket@rocrocket programming]$ who
rocrocket :0 2009-01-08 11:07
rocrocket pts/0 2009-01-08 11:23 (:0.0)
rocrocket pts/1 2009-01-08 14:15 (:0.0)
[rocrocket@rocrocket programming]$ who|cut -b -3
roc
roc
roc
[rocrocket@rocrocket programming]$ who|cut -b 3-
crocket :0 2009-01-08 11:07
crocket pts/0 2009-01-08 11:23 (:0.0)
crocket pts/1 2009-01-08 14:15 (:0.0)
想必你也看到了,-3表示从第一个字节到第三个字节,而3-表示从第三个字节到行尾。若是你细心,你能够看到这两种状况下,都包括了第三个字节“c”。
若是我执行who|cut -b -3,3-,你以为会如何呢?答案是输出整行,不会出现连续两个重叠的c的。看:
[rocrocket@rocrocket programming]$ who|cut -b -3,3-
rocrocket :0 2009-01-08 11:07
rocrocket pts/0 2009-01-08 11:23 (:0.0)
rocrocket pts/1 2009-01-08 14:15 (:0.0)
(6)给个以字符为定位标志的最简单的例子吧!
下面例子你似曾相识,提取第3,第4,第5和第8个字符:
[rocrocket@rocrocket programming]$ who|cut -c 3-5,8
croe
croe
croe
不过,看着怎么和-b没有什么区别啊?莫非-b和-c做用同样? 其实否则,看似相同,只是由于这个例子举的很差,who输出的都是单字节字符,因此用-b和-c没有区别,若是你提取中文,区别就看出来了,来,看看中文提取的状况:
[rocrocket@rocrocket programming]$ cat cut_ch.txt
星期一
星期二
星期三
星期四
[rocrocket@rocrocket programming]$ cut -b 3 cut_ch.txt
�
�
�
�
[rocrocket@rocrocket programming]$ cut -c 3 cut_ch.txt
一
二
三
四
看到了吧,用-c则会以字符为单位,输出正常;而-b只会傻傻的以字节(8位二进制位)来计算,输出就是乱码。
既然提到了这个知识点,就再补充一句,若是你学有余力,就提升一下。
当遇到多字节字符时,可使用-n选项,-n用于告诉cut不要将多字节字符拆开。例子以下:
[rocrocket@rocrocket programming]$ cat cut_ch.txt |cut -b 2
�
�
�
�
[rocrocket@rocrocket programming]$ cat cut_ch.txt |cut -nb 2
[rocrocket@rocrocket programming]$ cat cut_ch.txt |cut -nb 1,2,3
星
星
星
星
(7)域是怎么回事呢?解释解释:)
为何会有“域”的提取呢,由于刚才提到的-b和-c只能在固定格式的文档中提取信息,而对于非固定格式的信息则一筹莫展。这时候“域”就派上用场了。若是你观察过/etc/passwd文件,你会发现,它并不像who的输出信息那样具备固定格式,而是比较零散的排放。可是,冒号在这个文件的每一行中都起到了很是重要的做用,冒号用来隔开每个项。
咱们很幸运,cut命令提供了这样的提取方式,具体的说就是设置“间隔符”,再设置“提取第几个域”,就OK了!
以/etc/passwd的前五行内容为例:
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f 1
root
bin
daemon
adm
lp
看到了吧,用-d来设置间隔符为冒号,而后用-f来设置我要取的是第一个域,再按回车,全部的用户名就都列出来了!呵呵 有成就感吧!
固然,在设定-f时,也可使用例如3-5或者4-相似的格式:
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f 1,3-5
root:0:0:root
bin:1:1:bin
daemon:2:2:daemon
adm:3:4:adm
lp:4:7:lp
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f 1,3-5,7
root:0:0:root:/bin/bash
bin:1:1:bin:/sbin/nologin
daemon:2:2:daemon:/sbin/nologin
adm:3:4:adm:/sbin/nologin
lp:4:7:lp:/sbin/nologin
[rocrocket@rocrocket programming]$ cat /etc/passwd|head -n 5|cut -d : -f -2
root:x
bin:x
daemon:x
adm:x
lp:x
(8)若是遇到空格和制表符时,怎么分辨呢?我以为有点乱,怎么办?
有时候制表符确实很难辨认,有一个方法能够看出一段空格究竟是由若干个空格组成的仍是由一个制表符组成的。
[rocrocket@rocrocket programming]$ cat tab_space.txt
this is tab finish.
this is several space finish.
[rocrocket@rocrocket programming]$ sed -n l tab_space.txt
this is tab\tfinish.$
this is several space finish.$
看到了吧,若是是制表符(TAB),那么会显示为\t符号,若是是空格,就会原样显示。
经过此方法便可以判断制表符和空格了。
注意,上面sed -n后面的字符是L的小写字母哦,不要看错。
(9)我应该在cut -d中用什么符号来设定制表符或空格呢?
其实cut的-d选项的默认间隔符就是制表符,因此当你就是要使用制表符的时候,彻底就能够省略-d选项,而直接用-f来取域就能够了。
若是你设定一个空格为间隔符,那么就这样:
[rocrocket@rocrocket programming]$ cat tab_space.txt |cut -d ' ' -f 1
this
this
注意,两个单引号之间可确实要有一个空格哦,不能偷懒。
并且,你只能在-d后面设置一个空格,可不准设置多个空格,由于cut只容许间隔符是一个字符。
[rocrocket@rocrocket programming]$ cat tab_space.txt |cut -d ' ' -f 1
cut: the delimiter must be a single character
Try `cut --help' for more information.