【Linux】cat、tail、head、grep、sed查看文件任意几行的数据

grep结果太多, 可否只取前面10行匹配的结果

grep ...... | head -10

一、使用cat、tail、head组合

1、查看最后1000行的数据

cat filename | tail -n 1000

2、查看1000到3000行的数据

cat filename | head -n 3000 | tail -n +1000

1、cat filename 打印文件所有内容
2、tail -n 1000 打印文件最后1000行的数据
3、tail -n +1000 打印文件第1000行开始以后的内容
4、head -n 1000 打印前1000的内容

二、使用sed命令

显示1000到300行的数据

sed -n '1000,3000p' filename

============================================
输入ps,它就是我们今天的主角,ps是linux操作系统中最基本同时也是非常强大的进程查看命令,如果你对此命令不是十分了解,我们可以输入ps
–help命令来查看此命令的帮助信息。
通过帮助信息我们可以看到,ps命令的相关参数有很多,很多初学的朋友可能会看的一头雾水,不知道该怎么组合这些参数,下面小编就举一些实际应用例子,来介绍一些比较常用的查看进程的固定命令组合。
我们先来看第一个命令,ps

-l命令。这个命令和直接使用ps效果类似,但是不同之处在于使用ps命令获得结果很短,而使用-l参数之后将会较长、较详细的列出该PID的的信息列出,由于参数较多,小编就不一一介绍各个参数的含义了,如果想要了解参数的具体含义可以上网查看相关信息。
接着我们来看第二个命令ps

aux,有“-”符号和没有两者是有区别的,这个命令应该是比较常用的一个命令,作用就是列出目前所有的正在内存当中的程序,其中a表示显示现行终端机下的所有程序,包括其他用户的程序,u表示以用户为主的格式来显示程序状况,x表示显示所有程序,不以终端机来区分,它的相关参数也不少,例如user,表示属于那个使用者账号的,%CPU表示使用掉的CPU资源百分比,其他的参数就不一一的介绍了,有兴趣可以自行查看。

============================================
rl+ 是什么状态 linux ?是串联和是并联。

linux三大利器–grep|sed|awk

  • grep 文本查找
  • sed 行编辑器
  • awk 文本处理工具

grep

grep 比较简单 查找文本离不开正则 具体用法如从简单到复杂如

grep '[1-9]' 文件名 //匹配含有1到9数字
grep '[^1-9]' 文件名 //匹配除了1-9数字的其他字符
grep '^root' 文件名 //^变成头字符 以root开头
grep '^$' 文件名 //头和尾加起来 匹配空行
grep '.' 文件名 //匹配.
grep 'w' 文件名 //等同([a-zA-Z1-9_])
grep 'W' 文件名 //等同([^a-zA-Z1-9_])
grep 'b' 文件名 //表示单词分隔 如 b[a]b 就是a
grep 'sb+' 文件名 //匹配至少出现一次的sb
grep 'sb*' 文件名 //有s或者b都可以
grep '.' 文件名 //匹配任意字符

sed

  • 可用自动处理文件
  • 分析日志文件
  • 修改配置文件

  • sed的处理原则是行处理,而且不改变源文件

sed的格式

sed [options] ‘command’ file(s) //命令行格式
sed 'p' passwd #会打印出两行,因为sed的原理是读入一行,输出一行,此处再加上p命令打印出来的一行,所以最后会打印出两行
sed -n 'p'passwd #加了-n选项之后,只会打印出相关的行,那些不相关的行则不会打印出来

强大的grep,sed和awk–用案例来讲解

准备工作:

先简单了解grep,sed和awk功能  

1) grep 显示匹配特定模式的内容

  • grep -v ‘boy’ test.txt 过滤掉test.txt文件的boy,显示其余内容

  • grep ‘boy’ test.txt 显示test.txt文件中,和boy匹配的内容

  • -E 同时过滤多个”a|b”

  • -i 不区分大小写

  • –color=auto 设置颜色

2)sed 取各种内容,以行为单位取内容

  • -n取消默认输出

  • p=print

  • d=delete 

3)awk 取列

  • -F 指定分割符 如对“I am a student” 以空格为分割符,其将被分为4列,awk里有参数可以去任意列

  • NF 表示当前行记录域或列的个数

  • NR 显示当前记录号或行号

  • $1第一列 $2第二列 $0整行 $NF 最后一列        

案例一:如何过滤出em1的ip地址

[zhaohuizhen@localhost Test]$ ifconfig em1
em1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 10.0.0.8 netmask 255.255.255.0 broadcast 10.0.0.254
inet6 fe80::b283:feff:fed9:6a9a prefixlen 64 scopeid 0x20<link>
ether b0:83:fe:d9:6a:9a txqueuelen 1000 (Ethernet)
RX packets 13908772 bytes 4072069839 (3.7 GiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 982482 bytes 86260856 (82.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
device interrupt 40

步骤一

首先应该过滤出第二行inet 10.0.0.8 netmask 255.255.255.0 broadcast 10.0.0.254内容

方法一:grep命令

[zhaohuizhen@localhost Test]$ ifconfig em1 | grep 'inet '
 inet 10.0.0.8 netmask 255.255.255.0 broadcast 10.0.0.254

  
方法二:用sed命令

[zhaohuizhen@localhost Test]$ ifconfig em1 | sed -n '2p'
  inet 10.0.0.8 netmask 255.255.255.0 broadcast 10.0.0.254

方法三:用awk命令

[zhaohuizhen@localhost Test]$ ifconfig em1 | awk NR==2

  inet 10.0.0.8 netmask 255.255.255.0 broadcast 10.0.0.254

  
方法四:用head,tail命令

[zhaohuizhen@localhost Test]$ ifconfig em1 | head -2 | tail -1
  inet 10.0.0.8 netmask 255.255.255.0 broadcast 10.0.0.254

步骤二

过滤出第二行后,在过滤出ip地址

方法一:用cut命令

[zhaohuizhen@localhost Test]$ ifconfig em1 | sed -n '2p' | cut -c 14-25
   10.0.0.8

[zhaohuizhen@localhost Test]$ ifconfig em1 | grep 'inet ' | cut -d" " -f10
  10.0.0.8

方法二:用awk命令

[zhaohuizhen@localhost Test]$ ifconfig em1 | grep 'inet ' | awk -F '[ ]+' '{print $3}'
  10.0.0.8

用awk命令可以直接处理第二行,不用先将其过滤出来    

[zhaohuizhen@localhost Test]$ ifconfig em1 | awk -F '[ ]+' 'NR==2 {print $3}' 
  10.0.0.8

  
方法三:用sed命令

[zhaohuizhen@localhost Test]$ ifconfig em1 | sed -n '/inet /p' | sed 's#^.*et ##g' | sed 's# net.*$##g'
  10.0.0.8

此处用到了正则表达式(见http://www.cnblogs.com/ZGreMount/p/7656365.html),匹配的目标前面的字符串一般以^.开头,代表以任意字符开头,结尾写上要匹配的字符前面的几个字符,     如”^.addr “就匹配” inet addr “,而处理的目标后的内容则是开头写上要匹配字符后几个字符,加上以.$。如,“ Bcast:.$”就匹配“ Bcast:10.0.0.254 Mask:255.255.255.”

注:sed小括号分组功能

sed ‘s/********/……./标签’ #斜线可以被其它字符替换

前两条斜线中间部分内容********,可以使用正则表达式,后两条斜线中间内容…….不能使用正则表达式。

()是分组,在前面部分使用()括起来的内容,在后面部分可以使用1调用前面括号内内容。

如果有多个括号,那么依次是1,2,3,以此类推。

例如,直接取em1ip地址,不先过滤出第二行

[zhaohuizhen@localhost Test]$ ifconfig em1 | sed -n 's#^.*inet (.*) net.*$#1#gp'
  10.0.0.8

    
直接取出ip地址和子网掩码

[zhaohuizhen@localhost Test]$ ifconfig em1 | sed -n 's#^.*inet (.*) n.*k (.*) bro.*$#1 2#gp'
  10.0.0.8 255.255.255.0

案例二:输出文件a对应权限664

[zhaohuizhen@localhost Test]$ ll a 
   -rw-rw-r--. 1 zhaohuizhen zhaohuizhen 98 Oct 12 20:24 a

    
方法一:用awk命令

[zhaohuizhen@localhost Test]$ ll a | awk '{print $1}'|tr rwx- 4210|awk -F "" '{print $2+$3+$4 $5+$6+$7 $8+$9+$10}'
  664

    
解析:

1)ll a 长格式显示文件a    

[zhaohuizhen@localhost Test]$ ll a
  -rw-rw-r--. 1 zhaohuizhen zhaohuizhen 98 Oct 12 20:24 a

      
2)用awk命令,以空格为分隔符,取出第一列

[zhaohuizhen@localhost Test]$ ll a | awk '{print $1}'
  -rw-rw-r--.

      
3)用tr命令将rwx- 替换为4210

[zhaohuizhen@localhost Test]$ ll a | awk '{print $1}'|tr rwx- 4210
  0420420400.

      
4)用awk将上面的结果分割,然后相加得出结果

[zhaohuizhen@localhost Test]$ ll a | awk '{print $1}'|tr rwx- 4210|awk -F "" '{print $2+$3+$4 $5+$6+$7 $8+$9+$10}'
  664

方法二:用stat命令

[zhaohuizhen@localhost Test]$ stat a
File: ‘a’
Size: 98 Blocks: 8 IO Block: 4096 regular file
Device: fd02h/64770d Inode: 203491 Links: 1
Access: (0664/-rw-rw-r--) Uid: ( 1002/zhaohuizhen) Gid: ( 1002/zhaohuizhen)
Context: unconfined_u:object_r:user_home_t:s0
Access: 2017-10-14 09:20:34.337529787 +0800
Modify: 2017-10-12 20:24:27.512609708 +0800
Change: 2017-10-12 20:24:27.536609708 +0800
Birth: -

    
1)命令stat a结果包含文件a对应权限644,可以用前面的方法直接过滤出来

[zhaohuizhen@localhost Test]$ stat a | awk -F '[(/]' 'NR==4 {print $2}' 
  0664

    
2)stat命令包含需要结果,考虑stat命令是否有参数可以直接获得我们需要的结果

[zhaohuizhen@localhost Test]$ stat -c %a a
  664

案例三:输出文件a内容,不带空行,文件a内容如下:

[zhaohuizhen@localhost Test]$ cat a
"hello,this is a test"
I am a studeng My QQ is 1534612574

computer

book

river
tree

man
computer

book
river
tree
man

  
方法一:grep命令

[zhaohuizhen@localhost Test]$ grep -v '^$' a
"hello,this is a test"
I am a studeng My QQ is 1534612574
computer
book
river
tree
man
computer
book
river
tree
man

    
注释:-v 即排除;^$,开头和结尾间没有任何东西,即空行

方法二:用sed命令

[zhaohuizhen@localhost Test]$ sed '/^$/d' a
"hello,this is a test"
I am a studeng My QQ is 1534612574
computer
book
river
tree
man
computer
book
river
tree
man

注释:^$代表空行,d即delete

方法三:用awk命令

[zhaohuizhen@localhost Test]$ awk /[^$]/ a
"hello,this is a test"
I am a studeng My QQ is 1534612574
computer
book
river
tree
man
computer
book
river
tree
man

    
注释:^$代表空行,放在[]中代表非,即不匹配空行。

linux sed 多行处理详细总结

在正常情况下,sed将待处理的行读入模式空间,脚本中的命令就一条接着一条的对该行进行处理,直到脚本执行完毕,然后该行被输出,模式空间请空;然后重复刚才的动作,文件中的新的一行被读入,直到文件处理完备。但是,各种各样的原因,比如用户希望在某个条件下脚本中的某个命令被执行,或者希望模式空间得到保留以便下一次的处理,都有可能使得sed在处理文件的时候不按照正常的流程来进行。这个时候,sed设置了一些高级命令来满足用户的要求。如果想要学习sed的高级命令,首先要了解如下两个缓存区:

1、模式空间(pattern space)的定义:模式空间就是一个缓存区,保存sed刚刚从输入端读取的。
2、暂存空间(hold space)的定义:暂存空间就是在处理模式空间数据的时候,临时缓存数据用的。

还有几个命令参数:

  • g: 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
  • G: 将hold space中的内容append到pattern spacen后
  • h: 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
  • H: 将pattern space中的内容append到hold spacen后
  • x: 交换pattern space和hold space的内容

比如咱们想要倒排一个文件的内容,文件如下:

[[email protected] ~]$ cat tmp
  1-line
  2-line
  3-line

执行如下命令:

[[email protected] ~]$ sed '2,$G;h;$!d' tmp
  3-line
  2-line
  1-line

下面咱们逐步理解上面的执行过程

一、让咱们来分析一下如下三条命令:

  • 2,$G:从第二行到最后一行执行G命令
  • h:执行h命令
  • $!d:删除除了最后一行的所有行

二、具体的操作

1、扫描到第一行

  • 将1-line放入模式空间;此时模式空间还是1-line;
  • 直接执行h命令,此时暂存空间是1-line;
  • 执行d命令,删除了模式空间仅有的一行数据,删除之后,模式空间是空的

2、扫描到第二行

  • 将2-line放入模式空间
  • 执行G命令,将暂存空间的1-line添加到模式空间2-line的后面,此时模式空间是2-linen1-line;
  • 执行h命令,此时暂存空间的内容是2-linen1-line;
  • 执行d命令,模式空间被清空

3、扫描到第三行

  • 将3-line放入模式空间,
  • 执行G命令,将暂存空间的2-linen1-line添加到模式空间3-line的后面,此时模式空间是3-linen2-linen1-line;
  • 执行h命令,此时暂存空间的内容是3-linen2-linen1-line;
  • 不执行$!d;

4、直接输出 3-linen2-linen1-line

  • 当然,命令:sed ‘1!G;h;$!d’ tmp 也能有这个效果。

awk(报告生成器),grep(文本过滤器),sed(流编辑器)使用入门

未分类

linux下的文本三剑客

grep

egrep,grep,fgrep 
文本查找的需要
grep:根据模式搜索文本,并将符合模式的文本行显示出来。
pattern:文本符和正则表达式的元字符组合而成的匹配条件

grep [option] "pattern" file 
grep root /etc/passwd

-i:忽略大小写 
--color:匹配的字符高亮显示  alias
alias  grep='grep --color'
-v:反向查找 
-o:只显示被模式匹配的字符串(不显示行)

globbing

*:任意长度的任意字符
?:任意单个字符
[]:任意一个字符
[^]:其中任意一个非

正则表达式:Regular ExPression,REGEXP

元字符:
.:匹配任意单个字符
[]:匹配指定范围内的任意字符
[^]:匹配指定范围内的任意单个字符
[:digit:][:lower:][:upper:] []

字符匹配次数:
*:表示匹配前面的字符任意次(0-inf)
   a*b 
   a.*b
.*:表示任意长度的,任意字符
工作在贪婪模式 
?:匹配其前面的字符一个或0次。
    部分匹配 
  a?b 
{m,n}:匹配其前的字符至少m,至多n次。
   {1,}
  {0,3}
  a{1,3}
  a.{1,3}

位置锚定:

^:锚定行首,此字符后面的任意内容必须出现在行首。
grep "^root" /etc/passwd 

$:锚定行尾,此字符前面的任意内容必须出现在行尾。

grep "bash$" /etc/passwd 
^$:空白行 
grep '^$' /etc/passwd

数字:

[0-9]:

grep "[[:space:]][[:digit:]]$" 

r555t 

锚定单词:

<或b:其后面的任意字符必须出现在行首
>或b:其前面的任意字符必须出现在行尾。

This is root.
The user is mroot
rooter is dogs name.
chroot is a command.
grep "root>" test.txt 
grep "<root" test.txt 
grep "<root>" test.txt  

分组:

()
(ab)* :ab一个整体 

  后向引用

He love his lover.
She like her liker.
He  love his liker.
She like her lover.

grep 'l..e*l..e*' text.txt 
grep "l..e.*1" text.txt
grep "(l..e)" 

1:调用第一个左括号以及与之对应的右括号之间的内容。
2:
3:

/etc/inittab 
grep '([0-90]).*1$'  /etc/inittab 

REGEXP:regular Expresssion

pattern:文本的过滤条件

正则表达式:
basic REGEXP : 基本正则表达式
Extent REGEXP :扩展正则表达式

基本正则表达式

.
[]
[^]

次数匹配:
*:
?:0或1次
{m,n}:至少m次,至多n次

.*:

锚定:
^:
$:
<,b: 
>,b:

()
1,2....

grep:使用基本的正则表达式定义的模式来过滤文本的命令:

-i:忽略大小写 
-v 
-o 
--color 

-E 支持扩展的正则表达式 
-A  # :显示匹配行及以后多少行也显示 
  after 
-B:显示匹配行以及前面的n行
   before 
-C:显示匹配行以及前后的n行
   contest 
grep -A 2 ""  file 


扩展正则表达式:
   贪婪模式

字符匹配:
.
[]
[^]

次数匹配:
*:
?:
+:匹配其前面的字符至少一次
{m,n}

位置锚定:
^
$
<
>

分组:
():分组
1,2,3.....

或者:
a|b  or 

C|cat: 
(C|c)at: 

grep --color -E '^[[:space:]]+' /boot/grub/grub.conf 

grep -E = egrep 

egrep --color '<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-9]|25[0-5])>' 

(<([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-9]|25[0-5])>.){3}'<([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-5][0-9]|25[0-5])>.'

IPV4:
5类:
A B C D E 
A:1-127 
B:128-191 
C: 192--223 

<[1-9]|[1-9][0-9]|1[0-9]{2}|2[01][0-9]|22[0-30]>

sed(流编辑器)

sed基本用法:

sed:stream Editor 
行编辑器 
   文本编辑器 
   逐行处理文本 

全屏编辑器:vim 

内存空间:模式空间 
sed 模式空间 
匹配模式空间后,进行操作,将结果输出。仅对模式空间中的数据进行处理,而后,处理结束,将模式空间打印至屏幕;

默认sed不编辑原文件,仅对模式空间中的数据进行处理。

sed [option] [sed-scripts]

option:

-n:静默模式 
-i:直接修改原文件
-e scripts -e script:可以同时执行多个脚本。
-f /path/to/sed_scripts  命令和脚本保存在文件里调用。
  sed -f /path/to/scripts  file 
-r:表示使用扩展的正则表达式。
   只是进行操作,不显示默认模式空间的数据。

comamnd:

address:指定处理的行范围

sed 'addressCommand' file ... 
对符合地址范围进行操作。
Address: 
1.startline,endline 
 比如1,100
   $:最后一行
2./RegExp/ 
  /^root/
3./pattern1/,/pattern2/ 
  第一次被pattern匹配到的行开始,至第一次pattern2匹配到的行结束,这中间的所有行。
4.LineNumber 
   指定行 
5.startline,+N 
 从startline开始,向后的N行。

Command:
 d:删除符合条件的行。
     sed '3,$d' /etc/fstab
     sed '/oot/d' /etc/fstab 
注意:模式匹配,要使用 // 
    sed '1d' file 
p:显示符合条件的行 
 sed '/^//d' /etc/fstab 
 sed '/^//p' /etc/fstab 
   会显示两次
    先显示P匹配,再显示所有模式空间的数据。
a string:在指定的行后面追加新行,内容为"string"
sed '/^//a # hello world' /etc/fstab 
添加两行:
sed '/^//a #hello world n #hi' /etc/fstab 

i sting:在指定行的前面添加新行,内容为string。

r file:将指定的文件的内容添加在指定行后面。
  sed '2r /etc/issue'   /etc/fstab 
  sed '$r /etc/issue' /etc/fstab 

w file:将地址指定的范围的内容另存至另一文件中。
 sed '/oot/w /tmp/oot.txt' /etc/fstab 

s/pattern/string/:查找并替换 
     sed  's/oot/OOT/'  /etc/fstab 
sed 's/^//#/' /etc/fstab 
sed 's///#/'/etc/fstab 仅替换每一行第一次被模式匹配的串。
  加修饰符 
   g:全局替换 
   i:忽略大小写 
 sed 's///#/g'/etc/fstab

 s///:s###
 s@@@

sed 's#+##' 

后向引用

l..e:like----->liker 
     love----->lover 

sed 's#l..e#&r#' file
&:表示模式匹配的引用 

sed 's#l..e#1r#' file 

like---->Like
love---->Love 
sed 's#l(..e)#L1#g' file 


history |sed 's#[[:space:]]##g'
history | sed 's#^[[:space:]]##g'

sed ''dirname

例子????

 1.删除/etc/grub.conf文件中行首的空白符;
 sed  's/^[[:space:]]+//g' /etc/grub.conf 
 2.替换/etc/inittab文件中"id:3:initdefault:"一行中的3
 sed 's#id:3:init#id:5:initd#'
 sed 's@(id:)[0-9](:initdefault:)@152@g' /etc/inittab 
 3.删除/etc/inittab文件中的空白行。
  sed '/^$/d' /etc/inittab
4.删除/etc/inittab文件中开头的#号
sed 's/^#//'  
5.删除莫文件中开头的#号以及空白行。
sed 's/^[[:space:]]+//g' 
6.删除某文件中以空白字符后面跟#类的行中开头的空白字符以及#
sed -r 's/^[[:space:]]+#//g' 
7.取出一个文件路径的目录名称
echo '/etc/rc.d'|sed -r 's@^(/.*/)[^/]+/?@1@g'

awk(报告生成器)

grep :文本过滤器
sed:流编辑器 


grep option pattern file 
sed addresscommmand file 
sed 'comand/pattern/' file 

awk(报告生成器)

根据定义好的格式,显示出来。
nawk 
gawk
gnu awk 

awk option 'script' file file2 
awk [option] 'pattern {action}' file file2 

print 
printf 自定义显示格式


awk一次抽取一行,然后对每一行进行切割分片,每一片可以使用变量进行引用。
$0:表示引用一整行
$1:第一个切片
$2:第二个切片 

awk '{print $1}' text.txt 
awk '{print $1,$2}' text.txt

选项:

-F  指定分隔符
awk -F ''

awk 'BEGIN{OPS="#"}{print $1,$2}' test.txt
BEGIN{OPS=""} 输出分隔符

输出特定字符
awk '{print $1,"hello",$2,$3,$4,$5}' file 

awk 'BEGIN{print "line onenline twonline tree"}'

print的格式:
print item1,item2...

awk -F: 输入分隔符 
OFS="#"   输出分隔符

awk变量

awk内置变量
FS: filed separator,读取文本时,所用字段分隔符
RS:recordsepartor,输入文本信息所使用的换行符。
OFS:OUT filed separator 
ORS:Output ROw separator 

awk -F:
OFS="#"
FS=":"

awk内置变量之数据变量

NR: the number of input record ,awk命令所处理的记录,如果有多个文件,这个数据是所有处理的行数。
FNR:当前文件所处理的行是本文件第多少行。
NF:当前所处理的行有多少个字段。


awk '{print NF}' file 
awk '{print $NF}' file 
awk '{print NR}' file 

-v 定义变量

awk -v test="hello awk" '{print test}' 
awk -v test="hell awk" 'BEGIN{print test}'


awk  'BEGIN{test='hello awk',print test}'

printf 格式化显示

printf  format,item1,item2...

awk 'BEGIN{printf %c,}'
注意:printf不换行  

%d 
%e 
%f 
%g 

修饰符
-:左对齐 
%nd:显示宽度 
awk '{printf %-10s%-10sn,$1,$2}' file

awk的操作符

算术操作符

字符串操作符

布尔表达式

x < y 
x <= y 
x > y 
x != y 
x ~ y 匹配 
x !~ y 

表达式间的逻辑关系符

&& 
||

条件表达式

select?if-true-exp:if-false-exp 
a>b?a=1:b=2 

awk模式

1.正则表达式 /pattern/
2.表达式 
3.REGEXP 指定匹配范围 
4.BEGIN/END 
5Empty  


awk -F : '/^r/ {print $1}' /etc/passwd 
awk -F : '$3>=500{printf $1,$3}' /etc/passwd 
awk -F: '$3+1>=500{print $1,$3}' /etc/passwd

awk -F: '$7~"bash$"{print $1,$7}' /etc/passwd 
进行匹配测试
awk -F: '$7!~"bash$"{print $1,$7}' /etc/passwd 

awk -F: '/^r/,/^m/{print $1,$7}' /etc/passwd 

awk -F: '$3==0,$7~"bash"{print $1,$3,$7}' /etc/passwd 

awk -F '{printf "%-10s%-10s%-20sn",$1,$2,$3}' /etc/passwd 

BEGIN ,END 

awk -F: '$3==0,$7~"nologin"BEGIN{print "Username       ID    shell"}{printf "%-10s%-10s%-20sn"$1,$3,$7} END{print "ending"}' /etc/passwd 

action

1.ExPression 
2.control statements 
3.compound statements 
4.INput statment 
5 output statements 

控制语句

if-else

if(condition) {then-body} else {[else-body]}
eg:
awk -F:

while

while (condition){statement1;statement2;...}
循环每一字段 
length([string])

awk -F: '{i=1; while (1<=NF) if {(length($i)>4) {print $i}; i++}}'

df -hP |awk '{if($4 >=) Print $0}'


do while 
do{statement1,statement2,...} while(condition)

for 
for( ; ; ){statement1;statement2....}

awk -F: '{for(i=1:i<=NF;i++){if(length($i)>=4){print $i}}}'  /etc/passwd 

case 
switch (exprssion) {case value or /regexp/:statement1,statement2,...default:statement,....}

break和continue 
contine是遍历字段的 

next 
提前结束对本行文本的处理,并接着处理下一行,

数组

数组下表是从1开始的
awk[mon]=1 
awk[tus]=2 


for (var in arrary){statement,....}

awk -F: '{shell[$NF]++}END {for(A in shell) {print A,shell[A]}}' /etc/passwd 

nestat -tan 

netstat -tan |awk '/^tcp/{STATE[$NF]++}END{for (S in STATE){print S,STATE[S]}}'

awk '{count[$1]++}END{for ip in count}{printf "%-20s:%dn",ip,count[ip]}}'  access_log

使用sed或awk获取除最后两个字段之外的字段

字符串示例为:

/Users/yfan/Downloads/dsc20170801_jar/releases/com/netfinworks/ufs/ufs-client/ufs-client-2.0.0.jar

需求:如果使用斜杠/作为分隔符的话,可能每个字符串的字段数不同,这时需要取 除了最后两个字段外的其他字段字符串,所得结果应为如下形式:

/Users/yfan/Downloads/dsc20170801_jar/releases/com/netfinworks/ufs/ufs-client/

解决方法:

1、使用sed

[root@www ~]# b="/Users/yfan/Downloads/dsc20170801_jar/releases/com/netfinworks/ufs/ufs-client/2.0.0/ufs-client-2.0.0.jar"
[root@www ~]# a=`echo "/Users/yfan/Downloads/dsc20170801_jar/releases/com/netfinworks/ufs/ufs-client/2.0.0/ufs-client-2.0.0.jar" |awk -F'/' '{print $(NF-1)"/"$NF}'`
[root@www ~]# echo $b|sed -n "s#$a##gp"
/Users/yfan/Downloads/dsc20170801_jar/releases/com/netfinworks/ufs/ufs-client/

2、使用awk

[root@www ~]# b="/Users/yfan/Downloads/dsc20170801_jar/releases/com/netfinworks/ufs/ufs-client/2.0.0/ufs-client-2.0.0.jar"
[root@www ~]# echo $b |awk -F'/' '{gsub($(NF-1)"/"$NF,"");print}'
/Users/yfan/Downloads/dsc20170801_jar/releases/com/netfinworks/ufs/ufs-client/

如何使用Bash解析nginx.conf中server_name的第一个域名

问题

在指定的nginx.conf vhost配置文件中,如何获取server_name变量的第一个域名?
vhosts配置文件是与nginx.conf分离的,通过include引入,现在我能使用grep显示server_name的行内容,不过我仅想要第一个域名。
所以,如果我执行grep “server_name” /each/vhost/conf,将输出:

root@getyou:/home# grep "server_name" /home/site-configs/getyou
        server_name getyou.onl;
        server_name www.getyou.onl getme.onl www.getme.onl;
root@getyou:/home# grep "server_name" /home/site-configs/kevinpirnie
        server_name kevinpirnie.com www.kevinpirnie.com;
root@getyou:/home# grep "server_name" /home/site-configs/airsweepinc
        server_name airsweepinc.com www.airsweepinc.com;
root@getyou:/home# grep "server_name" /home/site-configs/themedepot
        server_name theme-depot.net www.theme-depot.net;

而我想输入下面的:

root@getyou:/home# grep "server_name" /home/site-configs/getyou
        getyou.onl
root@getyou:/home# grep "server_name" /home/site-configs/kevinpirnie
        kevinpirnie.com
root@getyou:/home# grep "server_name" /home/site-configs/airsweepinc
        airsweepinc.com
root@getyou:/home# grep "server_name" /home/site-configs/themedepot
        theme-depot.net

最佳答案

使用GNU grep和Perl正则:

$ grep -m1 -Poe 'server_name K[^; ]+' getyou
getyou.onl

(-m1 仅获取第一个匹配,-P Perl正则,-o 只打印匹配的部分。K 这之前匹配的都废弃,所以这之后的将由于-o打印)
或者,如果无法使用grep -P,可以使用同样效果的Perl:

$ perl -lne 'if (/server_name ([^ ;]+)/) {print $1; exit 0}' getyou

或者GNU sed:

$ sed -ne '/server_name/{s/.*server_name //; s/[; ].*//; p; q}' getyou

使用sed或awk显示指定行内容

文件内容为

[root@test1 test]# cat file.test
1
2
3
4
5
6
7
8
9
10

1. 显示第二行内容(指定行)

  • sed
[root@test1 test]# sed -n '2p' file.test
2
  • awk
[root@test1 test]# awk 'NR==2 {print $0}' file.test
2
[root@test1 test]# awk '{if(NR==2)print $0}' file.test
2

2. 显示第三行至第五行内容(指定行范围)

  • sed
[root@test1 test]# sed -n '3,5p' file.test
3
4
5
  • awk
[root@test1 test]# awk '{if(NR>2&&NR<6) print $0}' file.test
3
4
5
  • grep
[root@test1 test]# grep -C 1 4 file.test
3
4
5

3. 显示奇数行与偶数行

  • sed
[root@test1 test]# sed -n '1~2p' file.test
1
3
5
7
9
[root@test1 test]# sed -n '2~2p' file.test
2
4
6
8
10
[root@test1 test]# sed -n 'p;n' file.test
1
3
5
7
9
[root@test1 test]# sed -n 'n;p' file.test
2
4
6
8
10
  • awk
[root@test1 test]# awk 'NR%2==1' file.test
1
3
5
7
9
[root@test1 test]# awk 'NR%2==0' file.test
2
4
6
8
10
[root@test1 test]# awk '{if(NR%2==1) print $0}' file.test
1
3
5
7
9
[root@test1 test]#
[root@test1 test]# awk '{if(NR%2==0) print $0}' file.test
2
4
6
8
10

4. 显示匹配到的行

  • sed
[root@test1 test]# sed -n '/5/p' file.test
5 line 5
  • awk
[root@test1 test]# awk '/5/' file.test
5 line 5
  • grep
[root@test1 test]# grep 5 file.test
5 line 5

sed的12个练习题

1、复制/etc/rc.d/rc.sysinit文件至/tmp目录,将/tmp/rc.sysinit文件中的以至少一个空白字符开头的行的行首加#。

cp /etc/rc.d/rc.sysinit /tmp
sed -i 's/(^[[:space:]])/#1/g' /tmp/rc.sysinit

2、复制/boot/grub/grub.conf至/tmp目录中,删除/tmp/grub.conf文件中的行首的空白字符。

cp /boot/grub/grub.conf /tmp
sed -i 's/^[[:space:]]+//g' /tmp/grub.conf

3、删除/tmp/rc.sysinit文件中的以#开头,且后面跟了至少一个空白字符的行的#和空白字符。

sed -i 's@^#[[:space:]]+@@g' /tmp/rc.sysinit

4、为/tmp/grub.conf文件中前三行的行首加#号。

sed -i '1,3s@(^.)@#1@g' /tmp/grub.conf

5、将/etc/yum.repos.d/CentOS-Media.repo文件中所有的enabled=0或gpgcheck=0的最后的0修改为1

sed -i 's/enabled=0/enabled=1/g;s/gpgcheck=0/gpgcheck=1/g' /etc/yum.repos.d/CentOS-Media.repo

6、每4小时执行一次对/etc目录的备份,备份至/backup目录中,保存的目录名为形如etc-201504020202。

crontab -e
crontab -e 0*/4*** /etc /backup/etc-$(date +%Y%m%d%H%M)

7、每周2,4,6备份/var/log/messages文件至/backup/messages_logs/目录中,保存的文件名形如messages-20150402。

crontab -e
*00**2,4,6 cp -rf /var/log/messages /backup/message-$(date +%Y%m%d)

8、每天每两小时取当前系统/proc/meminfo文件中的所有以S开头的信息至/stats/memory.txt文件中。

crontab -e
1*/2**1,2,3,4,5 grep "^S" /proc/meminfo >> /stats/memry.txt

9、工作日的工作时间内,每两小时执行一次echo“howdy”。

crontab -e
1*/2**1,2,3,4,5 echo "howdy"

10、创建目录/tmp./testdir-当前日期时间

vim test1.sh
#!/bin/bash
#
mkdir /tmp/testdir-$(date +%Y%m%d)

11、在此目录创建100个空文件:file1-file100。

vim test2.sh
#!/bin/bash
#
for i in {1..100};do
touch /tmp/testdir-201609071346/file$i
done

12、显示/etc/passwd文件中位于第偶数行的用户的用户名。

vim test3.sh
#!/bin/bash
#
sed -n 'n;p' /etc/passwd | cut -d: -f1

linux sed在指定的行添加内容

在Linux的一些配置中总会要进行某个文件中的某行的操作,进行增加,修改,删除等操作。

而这里主要是进行的是指定的行添加数据的操作:

脚本如下:

sed -i '3i asdf 1.sh' 1.sh

这个就是在1.sh中的第3行加入asdf的数据。

首先看1.sh内容如下:

未分类

执行sed命令如下:

未分类

这个就是一个比较简单的操作,比较实用。