def grep linux

2018-04-20 16:35:57 kikajack 阅读数 3534
  • 第2课时 Web服务器1

    1、Linux实战运维案例初级视频课程(RHCSA-RHCE-RHCA精讲)2、Linux实战运维案例中级视频课程(RHCSA-RHCE-RHCA精讲)3、Linux实战运维案例高级视频课程(RHCSA-RHCE-RHCA精讲)

    207人学习 秦冰
    免费试看

grep 官方手册
awk 官方手册awk 学习资料

1. grep

grep 用于打印匹配指定模式的行。

1.1 介绍

grep 命令从输入文件中查找匹配到给定模式列表的行。发现匹配到的行后,默认情况下会复制这一行到标准输出流,也可以通过选项产生任何其他类型的输出。

grep 匹配文本时,对输入行长度没有限制(但受内存限制),并且可以匹配一行中的任意字符。如果输入文件的最后一个字节不是换行符,那么 grep 会提供一个。由于换行符也是模式列表的分隔符,因此无法在文本中匹配换行符。

1.2 调用 grep

grep [options] pattern input_file_names

选项可以有零个或多个。如果通过选项 -e pattern-f file 指定了模式(pattern),命令中的模式是不可见的。input_file_names 也可以有零个或多个。

1.2.1 命令行选项

grep 带有一组丰富的选项,分别来自 POSIX 或 GNU 扩展。长选项都是 GNU 扩展的,即使对于 POSIX 规范中的选项也是如此。

通用程序信息

  • --help:打印选项帮助信息并退出。
  • -V--version:将 grep 的版本号打印到标准输出流。

匹配控制

  • -e pattern--regexp=pattern:从命令行指定模式。如果此选项多次使用或与 -f (--file) 选项结合使用,搜索所有给定的模式。 (-e 由 POSIX 指定。)
  • -f file--file=file:从文件中获取模式,每行一个。如果此选项多次使用或与 -e--regexp)选项结合使用,搜索所有给定的模式。 空文件包含零个模式,因此不匹配任何内容。(-f 由 POSIX 指定)。
  • -i-y--ignore-case:忽略大小写,以便匹配只是大小写不同的字符。
  • -v--invert-match:对匹配到的结果取反,选择不匹配的行。(-v 由 POSIX 指定。)
  • -w--word-regexp:只选择那些包含整个单词的匹配的行。测试是匹配子字符串必须位于行首,或者以非单词组成字符开头。同样,它必须位于行尾,或者后面跟着一个非单词组成字符。单词组成字符是字母,数字和下划线。如果还指定了 -x,则此选项无效。
  • -x--line-regexp:只选择与整个行完全匹配的那些行。对于一个正则表达式模式,这就像括号中的模式,然后用’^’和’$’围绕它。 (-x 由 POSIX 指定。)

通用输出控制

  • -c``--count:抑制正常输出,相反,为每个输入文件打印一个匹配行数。使用 -v--invert-match)选项可以计算不匹配的行。
  • --color[=WHEN]``--colour[=WHEN]:将匹配(非空)字符串,匹配行,上下文行,文件名,行号,字节偏移量和分隔符(用于上下文行的字段和组)排列用转义序列包围后在终端上以彩色显示。对于粗体红色,颜色由环境变量 GREP_COLORS 定义,默认为’ms = 01; 31:mc = 01; 31:sl =:cx =:fn = 35:ln = 32:bn = 32:se = 36’ 粗体红色的匹配文本,品红色的文件名称,绿线的数字,绿色的字节偏移量,青色的分隔符和默认终端颜色。WHEN 可以是‘never’、‘always’ 或 ‘auto’。
  • -L``--files-without-match:抑制正常输出,相反,打印每个输入文件的名称,其中通常不会输出任何输出文件(from which no output would normally have been printed)。每个文件的扫描在第一次匹配时停止。
  • -l``--files-with-matches:抑制正常输出,相反,打印每个输出文件的名称,通常从哪个输出文件打印出来(from which output would normally have been printed)。 每个文件的扫描在第一场比赛时停止。
  • -m num``--max-count=num:匹配到指定次数后停止读取文件。如果输入是来自常规文件的标准输入,并且输出了 num 个匹配行,则 grep 可确保在退出前标准输入位于最后一个匹配行之后,而不管后面是否存在上下文行。这使调用进程能够恢复搜索。例如,以下 shell 脚本使用这个选项:
while grep -m 1 PATTERN
do
  echo xxxx
done < FILE

但以下可能无法正常工作,因为管道 pipe 不是常规文件:

# This probably will not work.
cat FILE |
while grep -m 1 PATTERN
do
  echo xxxx
done

当 grep 在 num 个匹配行后停止时,它输出任何后面的上下文行。由于上下文不包含匹配行,当遇到另一个匹配行时,grep 将停止。当还使用 -c--count 选项时,grep 不会输出大于 num 的计数。当使用 -v--invert-match 选项时,grep 在输出 num 不匹配行后停止。
- -o``--only-matching:仅打印匹配行的匹配(非空)部分,每个这样的部分位于单独的输出行上。输出行使用与输入相同的分隔符,如果还使用了 -z--null-data),则分隔符为空字节(请参阅其他选项)。
- -q``--quiet``--silent:不向标准输出写任何东西。如果发现任何匹配,即使检测到错误,也立即以零状态退出。另请参阅 -s--no-messages 选项。
- -s``--no-messages:抑制关于不存在或不可读文件的错误消息。

输出行的前缀控制(Output Line Prefix Control):

当要输出多个前缀字段时,顺序始终是文件名,行号和字节偏移量,无法指定顺序。
- -b``--byte-offset:在每行输出之前打印在输入文件中基于 0 的字节偏移量。如果指定了 -o--only-matching),则打印匹配部分本身的偏移量。当 grep 在 MS-DOS 或 MS-Windows 上运行时,打印的字节偏移取决于是否使用 -u--unix-byte-offsetsets)选项。
- -H``--with-filename:每次匹配时打印文件名。同时搜索多个文件时默认开启。
- -h``--no-filename:抑制输出前缀中的文件名。只搜索一个文件时默认开启。
- --label=LABEL:显示实际来自标准输入的输入作为来自文件 LABEL 的输入。这在使用 zgrep 这样的工具时特别有用,例如:

gzip -cd foo.gz | grep --label=foo -H something
  • -n``--line-number:在每个输出行的前面添加输入文件中基于 1 的行号。
  • -T``--initial-tab:确保实际行内容的第一个字符位于制表位 tab 上,以便对齐。对于将输出前缀(文件名、行号、字节偏移量)添加到实际内容的选项非常有用:-H-n-b。这也可能会预留空格来输出行号和字节偏移量,以使单个文件中的行全部从同一列开始。
  • -u``--unix-byte-offsets:只在 Windows 下有效。报告 Unix 风格的字节偏移量。该选项会导致 grep 报告字节偏移量,就像该文件是 Unix 样式的文本文件一样,即字节偏移量会忽略被删除的回车符。这将产生与在 Unix 机器上运行 grep 相同的结果。除非也使用 -b 选项,否则此选项不起作用。
  • -Z``--null:输出一个零字节(ASCII NUL 字符),而不是通常跟在文件名后面的字符。例如,’grep -lZ’在每个文件名后面输出一个零字节,而不是通常的换行符。该选项使输出清晰,即使在包含不正常字符(如换行符)的文件名中也是如此。这个选项可以和’find -print0’,’perl-0’,’sort -z’和’xargs -0’这样的命令一起使用来处理任意文件名,甚至那些包含换行符的文件名。

上下文行控制(Context Line Control):

上下文行是匹配行附近的非匹配行。只有在使用以下选项之一时才会输出它们。无论如何设置这些选项,grep 都不会多次输出任何给定的行。如果指定了 -o--only-matching)选项,则这些选项无效,并在使用时发出警告。
- -A num``--after-context=num:打印匹配行后的上下文行中的 num 行。
- -B num``--before-context=num:打印匹配行前的上下文行中的 num 行。
- -C num``-num``--context=num:打印匹配行前和匹配行后的上下文行中的 num 行。
- --group-separator=string:当使用 -A-B-C 选项时,在每组行之间打印字符串而不是 --
- --no-group-separator:当使用 -A-B-C 选项时,每组行之间不再打印字符串。

以下是关于 grep 如何选择分隔符以在前缀字段和行内容之间打印的一些要点:

  • 匹配行通常使用’:’作为前缀字段和实际行内容之间的分隔符。
  • 上下文(即非匹配行)行使用’-‘代替。
  • 当未指定上下文时,匹配行将被一个接一个地输出。
  • 指定上下文时,输入中相邻的行形成一个组,并且一个接一个地输出,而默认情况下,分隔符会出现在非相邻组之间。
  • 默认分隔符是’-‘行,它的存在和外观可以通过上述选项进行更改。
  • 每个组可能包含几个匹配行,当它们彼此足够靠近时,两个相邻的组连接并可合并成一个连续的组。

文件及目录选择(File and Directory Selection):

  • -a``--text:像处理文本一样处理二进制文件,相当于’–binary-files=text’选项。
  • --binary-files=type:如果文件的数据或元数据指示文件包含二进制数据,则假定该文件是 type 类型的。非文本字节表示二进制数据,这些输出字节是针对当前语言环境进行错误编码的输出字节(请参阅环境变量 Environment Variables),或者当没有给出 -z--null-data)选项时输入空字符(请参阅其他选项 Other Options)。
    默认情况下,type 是’binary’,并且 grep 发现输入的二进制数据不存在时会抑制输出,并抑制包含不正确编码数据的输出行。当某些输出被抑制时,grep 会跟随带有单行消息的任何输出,表示二进制文件匹配。
    如果 type 是’without-match’,当 grep 发现输入的二进制数据不存在时,它假定文件的其余部分不匹配。相当于 -I 选项。
    如果 type 是’text’,grep 会像处理文本一样处理二进制数据。相当于 -a 选项。
    当 type 是’binary’时,即使没有 -z--null-data)选项,grep 也可能将非文本字节视为行终止符。这意味着选择“binary”与“text”可以影响模式是否与文件匹配。例如,当 type 为’binary’时,模式’q$’可能会匹配紧接着为空字节的’q’,尽管当 type 为’text’时这不匹配。相反,当 type 为’binary’时,模式’.’(句点)可能不匹配空字节。
    警告:-a--binary-files=text)选项可能会输出二进制垃圾,如果输出是终端,并且终端驱动程序将其中的一部分解释为命令,则可能会产生副作用。另一方面,当阅读编码未知的文本文件时,在环境中使用 -a 或设置 LC_ALL='C' 可能会有所帮助,以便找到更多匹配,即使匹配对于直接不安全显示。

  • -D action``--devices=action:如果输入文件是设备,FIFO 或套接字,则使用 action 来处理它。如果 action 是“read”,则所有设备都被读取,就像它们是普通文件一样。如果 action 是“skip”,则设备,FIFO 和套接字将被默认跳过。默认情况下,如果设备在命令行上或者使用了 -R--deference-recursive)选项,则读取设备,如果递归地遇到设备并使用 -r--recursive)选项,则会跳过设备。该选项对通过标准输入读取的文件没有影响。

  • -d action``--directories=action:如果输入文件是目录,则使用 action 来处理。默认情况下,action 是’read’,这意味着对目录的读取跟普通文件一样(一些操作系统和文件系统不允许这样做,并且会导致 grep 打印每个目录的错误消息或者静默跳过它们)。如果 action 是“skip”,则目录会被静默跳过。如果 action 是’recurse’,则 grep 会以递归方式读取每个目录下的所有文件,遵循命令行符号链接并跳过其他符号链接,相当于 -r 选项。
  • --exclude=glob:跳过任何名称后缀匹配到模式 glob 的命令行文件,使用通配符匹配。名称后缀可以是全名,或在 / 之后和非 / 之前的部分。当递归搜索时,跳过基本名称与 glob 匹配的任何子文件,基本名称是最后一个 / 之后的部分。模式可以使用 *?[...] 作为通配符,而 \ 可以直接引用通配符或反斜线字符。
  • --exclude-from=file:跳过名称与 file 的模式相匹配的文件(使用通配符匹配,如 --exclude 下所述)。
  • --exclude-dir=glob:跳过任何名称后缀匹配模式 glob 的命令行目录。当递归搜索时,跳过其基名与 glob 匹配的任何子目录。忽略 glob 中的任何冗余结尾斜杠。
  • -I:处理二进制文件,就好像它不包含匹配数据一样; 这相当于 --binary-files=without-match 选项。
  • --include=glob:只搜索名称与 glob 匹配的文件,使用 --exclude 下所述的通配符匹配。
  • -r``--recursive:对于每个目录操作数,递归读取并处理该目录中的所有文件。遵循命令行上的符号链接,但跳过递归遇到的符号链接。注意,如果没有给出文件操作数,grep 将搜索工作目录。这与 --directories=recurse 选项相同。
  • -R``--dereference-recursive:对于每个目录操作数,按照所有符号链接递归地读取并处理该目录中的所有文件。

Other Options:

  • --line-buffered:在输出上使用行缓冲。这可能会导致性能损失。
  • -U``--binary:将文件视为二进制文件。默认情况下,在 Windows 下,grep 根据 --binary-files 选项所描述的猜测文件是文本文件还是二进制文件。如果 grep 认为该文件是一个文本文件,它将从原始文件内容中删除回车符(以使表达式的 ^$ 正常工作)。指定 -U 推翻了这种猜测,导致所有文件被读取并逐字传递给匹配机制。如果文件是每行末尾有 CR/LF 对的文本文件,则会导致一些正则表达式失败。此选项对 Windows 以外的平台没有影响。
  • -z``--null-data:将输入和输出数据视为行序列,每个数据以零字节(ASCII 的 NUL 字符)而不是换行符结尾。像 -Z--null 选项一样,该选项可以用于像 sort -z 这样的命令来处理任意文件名。

1.2.2 环境变量

grep 的行为受环境变量的影响。

GREP_OPTIONS:废弃。指定要放置在任何显式选项前面的默认选项。由于这会在编写可移植脚本时造成问题,所以在未来的 grep 发行版中将删除此功能。请改用别名或脚本。例如,如果 grep 位于目录 /usr/bin 中,则可以将 $HOME/bin 预先添加到 PATH 中,并创建包含以下内容的可执行脚本 $HOME/bin/grep

#! /bin/sh
export PATH=/usr/bin
exec grep --color=auto --devices=skip "$@"

GREP_COLOR:指定用于突出显示匹配(非空)文本的颜色。不赞成但仍支持使用 GREP_COLORS。GREP_COLORS 的’mt’,’ms’和’mc’功能优先于它。它只能指定用于突出显示任何匹配行中匹配的非空文本的颜色(当 -v 命令行选项被省略时的选定行,或者指定 -v 时的上下文行)。 默认值为’01;31’,表示终端默认背景上的粗体红色前景文字。

更多环境变量,参考 这里

1.2.3 退出状态

正常情况下,如果选择了一行,退出状态为 0,如果未选择行,则退出状态为 2,如果发生错误,退出状态为 2。但是,如果使用 -q--quiet--silent 选项并选择一行,即使发生错误,退出状态也为 0。其他 grep 实现可能会以大于 2 的状态退出。

1.3 正则表达式

参考 这里

1.4 使用

配合管道

基于上一个命令的输出信息进行 grep 匹配,而不是基于文件:

# echo "hello world" | grep "hello"
hello world

在文件中查找匹配模式的行

假设文件内容为:

123
hello
hello world
hello
hello world
666
fine
grep "hello world" /home/user/1.txt     # 匹配到一行
grep [0-9] /home/user/1.txt              # 匹配到两行

在多个文件中查找

grep "match_pattern" file_1 file_2 file_3 ...

输出包含匹配字符串的行数 -n,从 1 开始:

# grep -n "hello world" 1.txt 
3:hello world
5:hello world

统计包含匹配字符串的总行数:

# grep -c "hello world" 1.txt 
2

在多个文件中搜索并输出匹配到的文件:

grep -l "text" file1 file2 file3...

在多级目录中对文本进行递归搜索:

grep "text" . -r -n

忽略匹配样式中的字符大小写:

echo "hello world" | grep -i "HELLO"
hello

静默输出:

不会输出任何信息,如果命令运行成功返回 0,失败则返回非 0 值。一般用于条件测试。

grep -q "test" 1.txt

2. awk

awk 是一种程序设计语言,语言风格类似 C 语言,设计目的是写那种一行搞定事情的脚本,常用于文本处理的脚本。包含常用的内置函数,支持用户函数和动态正则表达式,支持数组。

awk 是一种弱类型语言,不需要提前声明就可以使用变量,变量的类型转换也是隐含的,在不同的上下文中变量可能是不同类型。awk 的字符串连结操作不需要任何操作符,只要把需要连结的串并列写在一起即可。

2.1 语法及命令

1. awk 命令调用语法

awk [options] 'script' var=value file(s)
awk -v var=value [options] 'script' file(s)
awk [options] -f scriptfile var=value file(s)

2. awk 常用选项

  • -F fs:指定输入分隔符,fs 可以是字符串或正则表达式,如 -F:
  • -v var=value:自定义用户变量,将外部变量传递给 awk
  • -f scripfile:从脚本文件中读取 awk 命令

3. awk 脚本结构

awk 'BEGIN{ print "start" } { commands } END{ print "end" }' file

awk 脚本通常由:BEGIN 语句块、能够使用模式匹配的通用语句块、END 语句块 3 部分组成,这三个部分都是可选的。脚本通常是被单引号或双引号中,所有指令用分号分隔。示例:

awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename
awk "BEGIN{ i=0 } { i++ } END{ print i }" filename

4. print 及 printf 指令

awk 中的 print 指令不带参数时打印当前行,参数可以是逗号分隔的列表。awk 的 print 中双引号被当作字符串连接符使用,例如:

# echo | awk '{a="a"; b="b"; print a,b}'
a b
# echo | awk '{a="a"; b="b"; print a","b}'
a,b

printf 指令跟 C 语言使用一样的格式化字符,以”%”开始,后跟一个或几个规定字符,用来确定输出内容格式。

格式 描述
%d 十进制有符号整数
%u 十进制无符号整数
%f 浮点数
%s 字符串
%c 单个字符
%p 指针的值
%e 指数形式的浮点数
%x %X 无符号以十六进制表示的整数
%o 无符号以八进制表示的整数
%g 自动选择合适的表示法
[root@VM_157_18_centos ~]# awk 'BEGIN{s="hello";f=124.113;i=246;c="hello"; printf("%s, %u, %.2f, %.2g, %X, %o, %c", s, f, f, f, i, i, c);}'
hello, 124, 124.11, 1.2e+02, F6, 366, h

2.2 awk 变量

1. 内置变量

  • $n:当前记录的第 n 个字段,空白符分隔一行为多个字段。
  • $0:执行过程中当前行的文本内容,完整的行。
  • NR:Number of Record,从 1 开始计数。awk 开始执行后,按照记录分隔符读取数据的次数(默认的记录分隔符为换行符,因此就是读取行数)。多个输入文件时,处理完第一个文件后,NR 继续累加而不会清空。
  • FNR:File Number of Record,每当处理一个新文件的时候,FNR 就从 1 开始计数。
  • NF:Number of Field,当前记录中字段的个数。
  • ARGC:命令行参数的个数。
  • ARGV:包含命令行参数的数组。
  • ARGIND:命令行中当前文件的位置(从 0 开始算)。
  • CONVFMT:数字转换格式(默认值为 %.6g)。
  • ENVIRON:环境变量关联数组。
  • ERRNO:最后一个系统错误的描述。
  • FIELDWIDTHS:字段宽度列表(用空格键分隔)。
  • FILENAME:当前输入文件的名。
  • FS:Field Separator,字段分隔符(默认是任何空白字符)。
  • IGNORECASE:如果为真,则进行忽略大小写的匹配。
  • OFMT:数字的输出格式(默认值是 %.6g)。
  • OFS:输出字段分隔符(默认值是一个空格)。
  • ORS:输出记录分隔符(默认值是一个换行符)。
  • RS:Record Separator,记录分隔符(默认是一个换行符)。
  • RSTART:由 match 函数所匹配的字符串的第一个位置。
  • RLENGTH 由 match 函数所匹配的字符串的长度。
  • SUBSEP 数组下标分隔符(默认值是 34)。

变量示例:

  • NR 及 NF 的用法:
# echo -e "line1 f2 f3\nline2 f4 f5\nline3 f6 f7" | awk '{print "Line No:"NR", No of fields:"NF, "$0="$0, "$1="$1, "$2="$2, "$3="$3}' 
Line No:1, No of fields:3 $0=line1 f2 f3 $1=line1 $2=f2 $3=f3
Line No:2, No of fields:3 $0=line2 f4 f5 $1=line2 $2=f4 $3=f5
Line No:3, No of fields:3 $0=line3 f6 f7 $1=line3 $2=f6 $3=f7
  • 使用 print $NF 可以打印一行中的最后一个字段,使用 $(NF-1) 打印倒数第二个字段,以此类推:
[root@VM_157_18_centos test]# echo -e "abc def\n123 456\nabc ggg" | awk '{print $(NF-1)}'
abc
123
abc
[root@VM_157_18_centos test]# echo -e "abc def\n123 456\nabc ggg" | awk '{print $(NF)}'
def
456
ggg
  • 打印完整行、行的第一个和最后一个字段:
[root@VM_157_18_centos test]# echo -e "abc def\n123 456\nabc ggg" | awk '{print $0, $1, $(NF)}'
abc def abc def
123 456 123 456
abc ggg abc ggg
  • 统计行数(使用 END 语句块):
[root@VM_157_18_centos test]# echo -e "abc def\n123 456\nabc ggg" | awk 'END{print NR}'
3

2. 传入外部变量到 awk

两种方式向 awk 传入变量:通过 -v 选项每次指定一个变量,或在 awk 的命令行参数中的语句块之后传入空格分隔的变量。

[root@VM_157_18_centos test]# echo | awk -v v1=100 -v v2=200 '{print v1, v2}'
100 200
[root@VM_157_18_centos test]# echo | awk '{print v1, v2}' v1=100 v2=200
100 200

2.3 awk 模式和操作

awk 脚本是由模式和操作组成。

2.3.1 awk 可以使用的模式有四种:

1. 正则表达式:/regular expression/

语法:

awk '/reg/{commands} {commands}'

工作流程:

示例:

# echo -e "abc \n123\n666" | awk '/[0-9]/{a=$0}{printf  a} '
123666
# echo -e "abc \n123\n666" | awk '/[0-9]/{print $0} '
123
666
# echo -e "abc \n123\n666" | awk '/[0-9]/{print $1} '
123
666

2. 关系表达式:使用运算符进行操作,可以是字符串或数字的比较测试。

可以判断行内的某个字段是否满足条件,满足则打印数据。支持的运算符有:==!=><>=<=

[root@VM_120_242_centos test]# echo -e 'abc ok\n1234\nxxx ok' | awk '$2=="ok"'
abc ok
xxx ok

3. 模式匹配表达式:用运算符 ~(匹配)和 ~!(不匹配)。

模式匹配时,可以将行内的某个字段使用正则表达式匹配。~ 表示开始模式匹配且打印匹配成功的行。

[root@VM_120_242_centos test]# echo -e 'abc ok\n1234\nxxx ok' | awk '$2 ~ /ok/'
abc ok
xxx ok

4. BEGIN 语句块、pattern 语句块、END 语句块

语法:

awk 'BEGIN{ commands } { commands } END{ commands }' file

工作流程:

  1. 执行 BEGIN{ commands } 语句块中的语句,BEGIN 关键字可以省略。
  2. 从文件或标准输入(stdin)读取一行后执行 { commands } 语句块,然后读下一行并再次执行 { commands } 语句块,直到最后一行。
  3. 当读至文件或输入流末尾时,执行 END{ commands } 语句块,END 关键字可以省略。

BEGIN 语句块用于只需执行一次的初始化等操作,比如变量初始化、打印输出表格的表头等。

END 语句块用于只需执行一次的清理操作,比如文件读取完毕后打印所有行的分析结果。

示例,其中 echo 输出的内容通过 -e 选项配合 \n 实现换行:

# echo -e "abd \n 1234" | awk 'BEGIN {print "Start"}  {print} END {print "END"}'
Start
abd 
 1234
END
# echo -e "abd \n 1234" | awk '{print "Start"}  {print} {print "END"}'
Start
abd 
 1234
END

2.3.2 操作

操作位于大括号内,由一个或多个命令、函数、表达式组成,用换行符分号分隔。模式匹配成功后,执行后面的操作。例如上面的 awk '/[0-9]/{a=$0}{printf a} ' 中的 {a=$0}{printf a} 就是操作。

2.4 输入输出

2.4.1 getline

从输入中每次获取一行输入。可以通过 while 循环,读完所有行。

1. expression | getline [var]

将管道前命令输出的结果作为 getline 的输入,每次读取一行。其中管道前的命令需要用双引号,例如 "cat 1.txt | getline var"。如果后面跟有 var,则将读取的内容保存到 var 变量中,否则会重新设置 $0 和 NF。

示例:

[root@VM_157_18_centos test]# cat 1.txt 
123
hello
hello world
hello
hello world
666
fine
[root@VM_157_18_centos test]# awk 'BEGIN{while("cat 1.txt" | getline var) print var}'
123
hello
hello world
hello
hello world
666
fine
[root@VM_157_18_centos test]# awk 'BEGIN{while("cat 1.txt" | getline ) print $0, NF}'
123 1
hello 1
hello world 2
hello 1
hello world 2
666 1
fine 1

2. getline [var]

从处理的文件中读取输入。同样,如果没有 var,则会设置 $0,并且这时候会更新 NF, NR 和 FNR:

[root@VM_157_18_centos test]# awk '{while(getline var) print var}' 1.txt 
hello
hello world
hello
hello world
666
fine

2.4.2 close

close 函数可以用于关闭已经打开的文件或者管道,很少会用到。

上面例子中 getline 函数的第一种形式用到管道,我们可以用 close 函数把这个管道关闭 close("cat statement.txt")

2.4.3 system

执行外部命令,例如:

[root@VM_157_18_centos test]# awk 'BEGIN{system("uname -a")}'
Linux VM_157_18_centos 3.10.0-693.el7.x86_64 #1 SMP Tue Aug 22 21:09:27 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

2.5 字符串

awk 的字符串连结操作不需要任何操作符,只要把需要连结的串并列写在一起即可。

[root@VM_157_18_centos test]# echo | awk '{T=123;print T;T=T+"abc";print T}'
123
123
[root@VM_157_18_centos test]# echo | awk '{T=123;print T;T=T"abc";print T}'
123
123abc
[root@VM_157_18_centos ~]# awk 'BEGIN{a="aaa";b="666";print a"   "b}'
aaa   666

字符串函数

定义

函数 解释
length [(String)] 返回 String 参数指定的字符串的长度(字符形式)。如果未给出 String 参数,则返回整个记录 $0 的长度。
blength [(String)] 返回 String 参数指定的字符串的长度(以字节为单位)。如果未给出 String 参数,则返回整个记录 $0 的长度。
substr( String, M, [ N ] ) 返回具有 N 参数指定的字符数量的子串。子串从 String 参数指定的字符串取得,其字符以 M 参数指定的位置开始。M 参数指定为将 String 参数中的第一个字符作为编号 1。如果未指定 N 参数,则子串到 String 的末尾。
index( String1, String2 ) 在由 String1 参数指定的字符串(其中有出现 String2 指定的参数)中,返回位置,从 1 开始编号。如果 String2 参数不在 String1 参数中出现,则返回 0(零)。
tolower( String ) 字符串中每个大写字符将更改为小写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。
toupper( String ) 字符串中每个小写字符将更改为大写。大写和小写的映射由当前语言环境的 LC_CTYPE 范畴定义。
split( String, A, [Ere] ) 将 String 参数指定的参数分割为数组元素 A[1], A[2], …, A[n],并返回 n 变量的值。此分隔可以通过 Ere 参数指定的扩展正则表达式进行,或用当前字段分隔符(FS 特殊变量)来进行(如果没有给出 Ere 参数)。除非上下文指明特定的元素还应具有一个数字值,否则 A 数组中的元素用字符串值来创建。
match( String, Ere ) 在 String 参数指定的字符串(Ere 参数指定的扩展正则表达式出现在其中)中返回位置(字符形式),从 1 开始编号,或如果 Ere 参数不出现,则返回 0(零)。RSTART 特殊变量设置为返回值。RLENGTH 特殊变量设置为匹配的字符串的长度,或如果未找到任何匹配,则设置为 -1(负一)。
gsub( Ere, Repl, [ In ] ) 除了正则表达式所有具体值被替代这点,它和 sub 函数完全一样地执行。
sub( Ere, Repl, [ In ] ) 用 Repl 参数指定的字符串替换 In 参数指定的字符串中的由 Ere 参数指定的扩展正则表达式的第一个具体值。sub 函数返回替换的数量。出现在 Repl 参数指定的字符串中的 &(和符号)由 In 参数指定的与 Ere 参数的指定的扩展正则表达式匹配的字符串替换。如果未指定 In 参数,缺省值是整个记录($0 记录变量)。

示例

[root@VM_157_18_centos ~]# awk 'BEGIN{info="hello world from awk,你好世界!";print length(info);}'
21
[root@VM_157_18_centos ~]# awk 'BEGIN{info="hello world from awk!";print substr(info,4,10);}'
lo world f
[root@VM_157_18_centos ~]# awk 'BEGIN{info="hello world from awk!";print index(info,"awk");}'
18
[root@VM_157_18_centos ~]# awk 'BEGIN{info="hello 666 world from 777 awk!";print match(info, /[0-9]/);}'
7
[root@VM_157_18_centos ~]# awk 'BEGIN{info="hello 666 world from 777 awk!";gsub(/[0-9]+/,"!",info);print info}'
hello ! world from ! awk!

2.6 数组

处理文本经常使用数组。数组索引(下标)可以是数字和字符串在awk中数组叫做关联数组(associative arrays)。awk 中的数组不必提前声明,也不必声明大小。数组元素用 0 或空字符串来初始化。

awk 中的数组下标从 1 开始,这与 C 的数组不一样。

awk 中的数组是默认是无序的关联数组。通过 for…in 循环得到是无序数组。对于数字下标的数组,如果需要得到有序数组,需要通过下标获得。例如:

[root@VM_157_18_centos test]# awk 'BEGIN{
 a["a"]=123;
 a[1]="abc";
 a["z"]=666;
 a["b"]=222;
 for (k in a) {
  print k, a[k];
 }
 len = length(a);
 for (i = 0; i < len; i++) {
  print i, a[i];
 }
}'
z 666
a 123
b 222
1 abc
0 
1 abc
2 
3

数组定义

数字做数组索引:

arr[1] = "a"
arr[2] = "123"

字符串做数组索引:

arr["a"] = "a"
arr["b"] = "123"

使用中 print arr[1] 会打印出 a;使用 print arr["b"] 会得到 123。

用 for 循环读数组的值

{ for(item in array) {print array[item]}; }       #输出的顺序是随机的
{ for(i=1;i<=len;i++) {print array[i]}; }         #Len是数组的长度

数组内置函数

数组长度 length

length 函数是 awk 内置函数,用于求数组长度。

[root@VM_157_18_centos test]# awk 'BEGIN{
 a[1]=123;
 a[2]="abc";
 print length(a);
}'
2

判断键值存在以及删除键值

[root@VM_157_18_centos ~]# awk 'BEGIN{
 a["a"]=123;
 a[1]="abc";
 a["z"]=666;
 a["b"]=222;
 if ("z" in a) {
    print "z in a"
 }
 if ("kkk" in a) {
    print "kkk in a"
 }
}'
z in a

二维数组

awk 中的二维数组用法跟 C 语言类似

  • 通过 array[i, j] 这样的形式访问。
  • 通过 if ( (i, j) in arr ) 判断元素是否存在,下标必须放置在圆括号中。
  • 通过 for ( key in arr ) 遍历数组。
[root@VM_157_18_centos ~]# awk 'BEGIN{awk 'BEGIN{
 for (i = 0; i < 4; i++) {
  for (j = 0; j < 4; j++) {
   arr[i, j] = i * j;
   print i"*"j, "=", i * j;
  }
 }
}'
0*0 = 0
0*1 = 0
...
3*2 = 6
3*3 = 9

2.7 内置函数

时间函数

函数 说明
mktime( YYYY MM dd HH MM ss[ DST]) 生成时间
strftime([format [, timestamp]]) 格式化时间输出,将时间戳转为时间字符串格式,见下表
systime() 时间戳,从 1970 年 1 月 1 日开始到当前时间的秒数

strftime日期和时间格式说明符:

格式 描述
%a 星期几的缩写(Sun)
%A 星期几的完整写法(Sunday)
%b 月名的缩写(Oct)
%B 月名的完整写法(October)
%c 本地日期和时间
%d 十进制日期
%D 日期 08/20/99
%e 日期,如果只有一位会补上一个空格
%H 用十进制表示24小时格式的小时
%I 用十进制表示12小时格式的小时
%j 从1月1日起一年中的第几天
%m 十进制表示的月份
%M 十进制表示的分钟
%p 12小时表示法(AM/PM)
%S 十进制表示的秒
%U 十进制表示的一年中的第几个星期(星期天作为一个星期的开始)
%w 十进制表示的星期几(星期天是0)
%W 十进制表示的一年中的第几个星期(星期一作为一个星期的开始)
%x 重新设置本地日期(08/20/99)
%X 重新设置本地时间(12:00:00)
%y 两位数字表示的年(99)
%Y 当前月份
%Z 时区(PDT)
%% 百分号(%)

示例:

[root@VM_157_18_centos ~]# awk 'BEGIN{tstamp=mktime("2018 04 20 16 28 59");print strftime("%c",tstamp);}'
Fri 20 Apr 2018 04:28:59 PM CST

[root@VM_157_18_centos ~]# awk 'BEGIN{print systime()}'
1524212859

[root@VM_157_18_centos ~]# awk 'BEGIN{print strftime("%Y-%m-%d %H:%M:%S", systime())}'
2018-04-20 16:31:14

算术函数

格式 描述
atan2( y, x ) 返回 y/x 的反正切。
cos( x ) 返回 x 的余弦;x 是弧度。
sin( x ) 返回 x 的正弦;x 是弧度。
exp( x ) 返回 x 幂函数。
log( x ) 返回 x 的自然对数。
sqrt( x ) 返回 x 平方根。
int( x ) 返回 x 的截断至整数的值。
rand( ) 返回任意数字 n,其中 0 <= n < 1。
srand( [expr] ) 将 rand 函数的种子值设置为 Expr 参数的值,或如果省略 Expr 参数则使用某天的时间。返回先前的种子值。

获取随机数示例:

[root@VM_157_18_centos ~]# awk 'BEGIN{srand(); print int(100*rand());}'
66
[root@VM_157_18_centos ~]# awk 'BEGIN{srand(); print int(100*rand());}'
29
[root@VM_157_18_centos ~]# awk 'BEGIN{srand(); print int(100*rand());}'
76

2.8 流程控制语句

awk 的流程控制语句跟 C 语言中的类似。

条件判断语句 if else

if (expresion)
  {...}
else if(expresion)
  {...}
else
  {...}

示例:

[root@VM_157_18_centos test]# awk 'BEGIN{
    score=60;
    if (socre > 60) {
        print "good";
    } else if (score <= 60) {
        print "danger";
    } else {
        print "hehe";
    }      
}'
danger

循环语句

for 循环

awk 中支持 C 风格的 for 循环:

for (init; ;expression) {
    ...
}

awk 也支持 for in 循环遍历数组:

for (var in arr) {
    ...
}

示例一:

[root@VM_157_18_centos test]# awk 'BEGIN{
 for (i = 5; i > 0; i--) {
  print i;
 }
}'
5
4
3
2
1

示例二:

[root@VM_157_18_centos test]# awk 'BEGIN{
 arr[1] = "a";
 arr[2]="123";
 for (v in arr) {
  print v, arr[v];
 }
}'
1 a
2 123

while 循环

while(expression) {
    ...
}

next 跳过后面的语句,continue 结束本次循环并开始下次循环

awk 就像是 C 语言中的 for 循环,循环执行次数就是文件或输入流的行数。next 指令类似 continue,跳过本次循环,开始下一次循环。下面示例跳过包含数字的行:

[root@VM_157_18_centos test]# echo -e 'abc\n123\nddd\n333\n666' | awk '/[0-9]/{next}{print NR, $0}'
1 abc
3 ddd
2016-08-11 21:06:05 u011003120 阅读数 66225
  • 第2课时 Web服务器1

    1、Linux实战运维案例初级视频课程(RHCSA-RHCE-RHCA精讲)2、Linux实战运维案例中级视频课程(RHCSA-RHCE-RHCA精讲)3、Linux实战运维案例高级视频课程(RHCSA-RHCE-RHCA精讲)

    207人学习 秦冰
    免费试看
linux grep命令
 
不定时更新中。。。

一、作用

百度
 

二、格式

grep [options] ‘pattern’ filename
 

三、option主要参数

 
下面所列的参数主要是一些常用的参数。
编号 参数 解释
1 --version or -V grep的版本
2 -A 数字N 找到所有的匹配行,并显示匹配行后N行
3 -B 数字N 找到所有的匹配行,并显示匹配行前面N行
4 -b 显示匹配到的字符在文件中的偏移地址
5 -c 显示有多少行被匹配到
6 --color 把匹配到的字符用颜色显示出来
7 -e 可以使用多个正则表达式
8 -f FILEA FILEB FILEA在FILEAB中的匹配
9 -i 不区分大小写针对单个字符
10 -m 数字N 最多匹配N个后停止
11 -n 打印行号
12 -o 只打印出匹配到的字符
13 -R 搜索子目录
14 -v 显示不包括查找字符的所有行
 
 
新建一个test.txt,里面内容如下:
root@Ubunut10:~/shell# cat test.txt
a
bc
def
ght12
abc999
tydvl658
123
456
789abc
 
 

1.--version

显示grep的版本号
 
[root@localhost shell]# grep --version
GNU grep 2.6.3
 
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
 
[root@localhost shell]#
 

2. -A 数字N

找到所有的匹配行,并显示匹配行后面N行
[root@localhost shell]# grep -A 2 "a" test.txt
a             //匹配字符’a’ 后面两行
bc
def
--
abc999
tydvl658
123
--
789abc
[root@localhost shell]#
 

3.-B 数字N

找到所有的匹配行,并显示匹配行前面N行
[root@localhost shell]# grep -B 2 "a" test.txt
a         
--
def
ght12
abc999    //匹配字符’a’ 前面两行
--
123
456
789abc
[root@localhost shell]#
 

4.-b

显示匹配到的字符在文件中的偏移地址
[root@localhost shell]# grep -b "a" test.txt
0:a            //在文件中的偏移地址
15:abc999
39:789abc
[root@localhost shell]#
 

5. -c

显示有多少行被匹配到
[root@localhost shell]# grep -c "a" test.txt
3   //在整个txt中,共有三个字符’a’被匹配到
[root@localhost shell]#
 

6.--color

把匹配到的字符用颜色显示出来
 
 

7.-e

可以使用多个正则表达式
[root@localhost shell]# grep -e "a" -e "1" test.txt
a                //查找txt中字符 ‘a’  和 字符 ‘1’
ght12
abc999
123
789abc
[root@localhost shell]#
 

8.-f FILEA FILEB

FILEA在FILEAB中的匹配
[root@localhost shell]# cat test.txt
a
bc
def
ght12
abc999
tydvl658
123
456
789abc
[root@localhost shell]# cat test1.txt
abc
[root@localhost shell]# grep -f test.txt test1.txt
abc
[root@localhost shell]# grep -f test1.txt test.txt
abc999
789abc
[root@localhost shell]#
 
 

9.-i

不区分大小写
[root@localhost shell]# cat test1.txt
ab
Ac
6356
AKF57
[root@localhost shell]# grep -i "a" test1.txt
ab             //找出所有字符’a’ 并且不区分大小写
Ac
AKF57
[root@localhost shell]#
 
 

10.-m 数字N

最多匹配N个后停止
[root@localhost shell]# grep -m 2 "a" test.txt
a
abc999     //匹配2个后停止
[root@localhost shell]#
 

11.-n

打印行号
[root@localhost shell]# grep -n -m 2 "a" test.txt
1:a          //打印出匹配字符的行号
5:abc999
[root@localhost shell]#
 

12.-o

会打印匹配到的字符
[root@localhost shell]# grep -n -o "a" test.txt
1:a
5:a
9:a
[root@localhost shell]#
 

13.-R

搜索子目录
[root@localhost shell]# mkdir 666      //创建一个子目录
[root@localhost shell]# cp test.txt 666/  //将txt复制到子目录里面
[root@localhost shell]# ls
666  test1.txt  test.txt              //当前目录有两个txt和一个子目录
[root@localhost shell]# grep "a" *
test1.txt:ab                       //只在当前目录查找字符’a’
test.txt:a
test.txt:abc999
test.txt:789abc
[root@localhost shell]# grep -R "a" *
666/test.txt:a                    //在当前目录和子目录查找字符’a’
666/test.txt:abc999
666/test.txt:789abc
test1.txt:ab
test.txt:a
test.txt:abc999
test.txt:789abc
[root@localhost shell]#
 

14.-v

显示不包括查找字符的所有行
[root@localhost shell]# grep -v "a" test.txt
bc
def
ght12
tydvl658
123
456
[root@localhost shell]#
 
 

四、pattern主要参数

 
编号 参数 解释
1 ^ 匹配行首
2 $ 匹配行尾
3 [ ] or [ n - n ] 匹配[ ]内字符
4 . 匹配任意的单字符
5 * 紧跟一个单字符,表示匹配0个或者多个此字符
6 \ 用来屏蔽元字符的特殊含义
7 \? 匹配前面的字符0次或者1次
8 \+ 匹配前面的字符1次或者多次
9 X\{m\} 匹配字符X m次
10 X\{m,\} 匹配字符X 最少m次
11 X\{m,n\} 匹配字符X m---n 次
12 \(666\) 标记匹配字符,如666 被标记为1,随后想使用666,直接以 1 代替即可
13 \| 表示或的关系
 
 
新建一个text.txt
[root@localhost shell]# cat test.txt
a
bcd
1
233
abc123
defrt456
123abc
12568teids
abcfrt568
[root@localhost shell]#
 

1.^

匹配行首
 
[root@localhost shell]# grep -n '^a' test.txt
1:a               //匹配以字符’a’开头的
5:abc123
9:abcfrt568
[root@localhost shell]#
 
[root@localhost shell]# grep -n '^abc' test.txt
5:abc123         //匹配以字符串”abc”开头的
9:abcfrt568
[root@localhost shell]#
 

2.$

匹配行尾
[root@localhost shell]# grep -n '33$' test.txt
4:233           //匹配以字符串”33”结束的
[root@localhost shell]# grep -n '3$' test.txt
4:233          //匹配以字符’3’结束的
5:abc123
[root@localhost shell]#
 

3.[ ]

匹配 [ ]内的字符,
可以使用单字符
如 [ 1] 即匹配含有字符’1’的字符串(示例1),
如 [ a] 即匹配含有字符’a’的字符串(示例2),
如 [ 1 2 3 ] 即匹配含有字符’1’ 或者 ’2’ 或者’3’ 的字符串(示例3),
也可以使用字符序列,用字符 ‘-’ 代表字符序列
如 [ 1-3 ] 即匹配含有字符’1’ 或者 ’2’ 或者’3’ 的字符串(示例4)
如 [ 1-3  a-b] 即匹配含有字符’1’ 或者 ’2’ 或者’3’ 或者 ’a’ 或者 ’b’的字符串(示例5)
 
示例1:
[root@localhost shell]# grep -n --color '[1]' test.txt
3:1
5:abc123
7:123abc
8:12568teids
 
 
示例2:
[root@localhost shell]# grep -n --color '[a]' test.txt
1:a
5:abc123
7:123abc
9:abcfrt568
 
 
示例3:
[root@localhost shell]# grep -n --color  '[1 2 3]' test.txt
3:1
4:233
5:abc123
7:123abc
8:12568teids
 
 
示例4:
[root@localhost shell]# grep -n --color '[1-3]' test.txt
3:1
4:233
5:abc123
7:123abc
8:12568teids
[root@localhost shell]#
 
 
示例5:
[root@localhost shell]# grep -n --color '[1-3 a-b]' test.txt
1:a
2:bcd
3:1
4:233
5:abc123
7:123abc
8:12568teids
9:abcfrt568
[root@localhost shell]#
 
 

4. .

匹配任意的单字符
[root@localhost shell]# grep -n --color  '^.3' test.txt
4:233                     //任意字符开头然后第二个字符为 ‘3’
[root@localhost shell]# grep -n --color  '^..3' test.txt
4:233                    //任意两个字符开头,然后第三个字符为 ‘3’
7:123abc
[root@localhost shell]#
 
 

5. *

紧跟一个单字符,表示匹配0个或者多个此字符
下面例子的意思是,匹配字符’3’ 0次或者多次
[root@localhost shell]#  grep -n --color  '3*' test.txt
1:a
2:bcd
3:1
4:233
5:abc123
6:defrt456
7:123abc
8:12568teids
9:abcfrt568
10:3
 
 
下面例子的意思是:匹配字符串”23”,但是 ‘3’ 被匹配的次数 >= 0
[root@localhost shell]# grep -n --color '23*' test.txt
4:233      
5:abc123
7:123abc
8:12568teids
[root@localhost shell]#
 
 

6. \

用来屏蔽元字符的特殊含义
下面的例子的意思是 在字符串 "365.398" 中,查找’.’这个字符,而不是任意单字符
[root@localhost shell]# echo "365.398" | grep --color '.'
365.398
[root@localhost shell]# echo "365.398" | grep --color '\.'
365.398
[root@localhost shell]#
 
 
 

7. \?

匹配前面的字符0 次或者 多次
[root@localhost shell]# grep -n --color '3\?' test.txt
1:a
2:bcd
3:1
4:233
5:abc123
6:defrt456
7:123abc
8:12568teids
9:abcfrt568
 
 
下面例子的意思是:匹配字符串”33”但是 第二个字符‘3’只能匹配0次或者1次,因此实际匹配到的字符有“33 ”和 ‘3’这两种
[root@localhost shell]# grep -n --color '33\?' test.txt
4:233   
5:abc123
7:123abc
 
 
下面例子的意思是:匹配字符串”23”但是 第二个字符‘3’只能匹配0次或者1次,因此实际匹配到的字符有“23 ”和 ‘2’这两种
[root@localhost shell]# grep -n --color '23\?' test.txt
4:233
5:abc123
7:123abc
8:12568teids
[root@localhost shell]#
 
 

8. \+  

匹配前面的字符1次或者多次
[root@localhost shell]# grep -n --color '3\+' test.txt
4:233
5:abc123
7:123abc
 
 

9.X\{m\}

匹配字符X m次
[root@localhost shell]# grep -n --color '3\{1\}' test.txt
4:233
5:abc123
7:123abc
 
 

10.X\{m,\}

匹配字符X 最少m次
[root@localhost shell]# grep -n --color '3\{1,\}' test.txt
4:233
5:abc123
7:123abc
[root@localhost shell]#
 
 

11.X\{m,n\}

匹配字符X m---n 次
[root@localhost shell]# grep -n --color '3\{0,1\}' test.txt
1:a
2:bcd
3:1
4:233
5:abc123
6:defrt456
7:123abc
8:12568teids
9:abcfrt568
[root@localhost shell]#
 
 

13. \|

表示或的关系
[root@localhost shell]# grep -n --color '\(ab\|23\)' test.txt
4:233
5:abc123
7:123abc
9:abcfrt568
 
 

五、示例

仅使用grep获取到ip,不使用其他 如 cut sed  awk 命令
[root@localhost shell]# ifconfig eth0 | grep -o '\(inet addr:\)\([0-9]\{1,\}\.\?\)\{1,\}' | grep --color -o '\([0-9]\{1,\}\.\?\)\{1,\}'
 
 
菜鸟一枚,如有错误,多多指教。。。
 
2016-03-09 14:15:14 it_taojingzhan 阅读数 222
  • 第2课时 Web服务器1

    1、Linux实战运维案例初级视频课程(RHCSA-RHCE-RHCA精讲)2、Linux实战运维案例中级视频课程(RHCSA-RHCE-RHCA精讲)3、Linux实战运维案例高级视频课程(RHCSA-RHCE-RHCA精讲)

    207人学习 秦冰
    免费试看
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://itshine.blog.51cto.com/648476/645466

1、程序和进程;

程序是为了完成某种任务而设计的软件,比如OpenOffice是程序。什么是进程呢?进程就是运行中的程序。

一个运行着的程序,可能有多个进程。比如 LinuxSir.Org 所用的WWW服务器是apache服务器,当管理员启动服务后,可能会有好多人来访问,也就是说许多用户来同时请求httpd服务,apache服务器将会创建有多个httpd进程来对其进行服务。

 

 

1.1 进程分类;

进程一般分为交互进程、批处理进程和守护进程三类。

值得一提的是守护进程总是活跃的,一般是后台运行,守护进程一般是由系统在开机时通过脚本自动 激活启动或超级管理用户root来启动。比如在Fedora或Redhat中,我们可以定义httpd 服务器的启动脚本的运行级别,此文件位于/etc/init.d目录下,文件名是httpd,/etc/init.d/httpd 就是httpd服务器的守护程序,当把它的运行级别设置为3和5时,当系统启动时,它会跟着启动。

[root@localhost ~]# chkconfig --level 35 httpd on

由于守护进程是一直运行着的,所以它所处的状态是等待请求处理任务。比如,我们是不是访问 LinuxSir.Org ,LinuxSir.Org 的httpd服务器都在运行,等待着用户来访问,也就是等待着任务处理。

1.2 进程的属性;

进程ID(PID):是唯一的数值,用来区分进程;

父进程和父进程的ID(PPID);

启动进程的用户ID(UID)和所归属的组(GID);

进程状态:状态分为运行R、休眠S、僵尸Z;

进程执行的优先级;

进程所连接的终端名;

进程资源占用:比如占用资源大小(内存、CPU占用量);

1.3 父进程和子进程;

他们的关系是管理和被管理的关系,当父进程终止时,子进程也随之而终止。但子进程终止,父进程并不一定终止。比如httpd服务器运行时,我们可以杀掉其子进程,父进程并不会因为子进程的终止而终止。

在进程管理中,当我们发现占用资源过多,或无法控制的进程时,应该杀死它,以保护系统的稳定安全运行;

2、进程管理;

对于Linux进程的管理,是通过进程管理工具实现的,比如ps、kill、pgrep等工具;

2.1 ps 监视进程工具;

ps 为我们提供了进程的一次性的查看,它所提供的查看结果并不动态连续的;如果想对进程时间监控,应该用top工具;

2.1.1 ps 的参数说明;

ps 提供了很多的选项参数,常用的有以下几个;

l 长格式输出;

u 按用户名和启动时间的顺序来显示进程;

j 用任务格式来显示进程;

f 用树形格式来显示进程;

a 显示所有用户的所有进程(包括其它用户);

x 显示无控制终端的进程;

r 显示运行中的进程;

ww 避免详细参数被截断;

我们常用的选项是组合是aux 或lax,还有参数f的应用;

ps aux 或lax输出的解释;

USER      进程的属主;

PID       进程的ID;

PPID 父进程;

%CPU      进程占用的CPU百分比;

%MEM      占用内存的百分比;

NI           进程的NICE值,数值大,表示较少占用CPU时间;

VSZ 进程虚拟大小;

RSS 驻留中页的数量;

WCHAN

TTY 终端ID

STAT 进程状态

 

D    Uninterruptible sleep (usually IO)

R    正在运行可中在队列中可过行的;

S    处于休眠状态;

T    停止或被追踪;

W    进入内存交换(从内核2.6开始无效);

X    死掉的进程(从来没见过);

Z    僵尸进程;

 

<           优先级高的进程

N    优先级较低的进程

L    有些页被锁进内存;

s    进程的领导者(在它之下有子进程);

l    is multi-threaded (using CLONE_THREAD, like NPTL pthreads do)

+                  位于后台的进程组;

 

WCHAN     正在等待的进程资源;

START 启动进程的时间;

TIME      进程消耗CPU的时间;

COMMAND 命令的名称和参数;

2.1.2 ps 应用举例;

实例一:ps aux 最常用

[root@localhost ~]# ps -aux |more

可以用 | 管道和 more 连接起来分页查看;

[root@localhost ~]# ps -aux > ps001.txt

[root@localhost ~]# more ps001.txt

这里是把所有进程显示出来,并输出到ps001.txt文件,然后再通过more 来分页查看;

实例二:和grep 结合,提取指定程序的进程;

[root@localhost ~]# ps aux |grep httpd

root 4187 0.0 1.3 24236 10272 ? Ss 11:55 0:00 /usr/sbin/httpd

apache 4189 0.0 0.6 24368 4940 ? S 11:55 0:00 /usr/sbin/httpd

apache 4190 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd

apache 4191 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd

apache 4192 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd

apache 4193 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd

apache 4194 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd

apache 4195 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd

apache 4196 0.0 0.6 24368 4932 ? S 11:55 0:00 /usr/sbin/httpd

root 4480 0.0 0.0 5160 708 pts/3 R+ 12:20 0:00 grep httpd

实例二:父进和子进程的关系友好判断的例子

[root@localhost ~]# ps auxf |grep httpd

root 4484 0.0 0.0 5160 704 pts/3 S+ 12:21 0:00 \_ grep httpd

root 4187 0.0 1.3 24236 10272 ? Ss 11:55 0:00 /usr/sbin/httpd

apache 4189 0.0 0.6 24368 4940 ? S 11:55 0:00 \_ /usr/sbin/httpd

apache 4190 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd

apache 4191 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd

apache 4192 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd

apache 4193 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd

apache 4194 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd

apache 4195 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd

apache 4196 0.0 0.6 24368 4932 ? S 11:55 0:00 \_ /usr/sbin/httpd

这里用到了f参数;父与子关系一目了然;

2.2 pgrep

pgrep 是通过程序的名字来查询进程的工具,一般是用来判断程序是否正在运行。在服务器的配置和管理中,这个工具常被应用,简单明了;

用法:

#ps 参数选项 程序名

常用参数

-l 列出程序名和进程ID;

-o 进程起始的ID;

-n 进程终止的ID;

举例:

[root@localhost ~]# pgrep -lo httpd

4557 httpd

[root@localhost ~]# pgrep -ln httpd

4566 httpd

[root@localhost ~]# pgrep -l httpd

4557 httpd

4560 httpd

4561 httpd

4562 httpd

4563 httpd

4564 httpd

4565 httpd

4566 httpd

[root@localhost ~]# pgrep httpd

4557

4560

4561

4562

4563

4564

4565

4566

3、终止进程的工具 kill 、killall、pkill、xkill;

终止一个进程或终止一个正在运行的程序,一般是通过 kill 、killall、pkill、xkill 等进行。比如一个程序已经死掉,但又不能退出,这时就应该考虑应用这些工具。

另外应用的场合就是在服务器管理中,在不涉及数据库服务器程序的父进程的停止运行,也可以用这 些工具来终止。为什么数据库服务器的父进程不能用这些工具杀死呢?原因很简单,这些工具在强行终止数据库服务器时,会让数据库产生更多的文件碎片,当碎片 达到一定程度的时候,数据库就有崩溃的危险。比如mysql服务器最好是按其正常的程序关闭,而不是用pkill mysqld 或killall mysqld 这样危险的动作;当然对于占用资源过多的数据库子进程,我们应该用kill 来杀掉。

3.1 kill

kill的应用是和ps 或pgrep 命令结合在一起使用的;

kill 的用法:

kill [信号代码]   进程ID

注:信号代码可以省略;我们常用的信号代码是 -9 ,表示强制终止;

举例:

[root@localhost ~]# ps auxf |grep httpd

root 4939 0.0 0.0 5160 708 pts/3 S+ 13:10 0:00 \_ grep httpd

root 4830 0.1 1.3 24232 10272 ? Ss 13:02 0:00 /usr/sbin/httpd

apache 4833 0.0 0.6 24364 4932 ? S 13:02 0:00 \_ /usr/sbin/httpd

apache 4834 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd

apache 4835 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd

apache 4836 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd

apache 4837 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd

apache 4838 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd

apache 4839 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd

apache 4840 0.0 0.6 24364 4928 ? S 13:02 0:00 \_ /usr/sbin/httpd

我们查看httpd 服务器的进程;您也可以用pgrep -l httpd 来查看;

我们看上面例子中的第二列,就是进程PID的列,其中4830是httpd服务器的父进程,从4833-4840的进程都是它4830的子进程;如果我们杀掉父进程4830的话,其下的子进程也会跟着死掉;

[root@localhost ~]# kill 4840 注:杀掉4840这个进程;

[root@localhost ~]# ps -auxf |grep httpd 注:查看一下会有什么结果?是不是httpd服务器仍在运行?

[root@localhost ~]# kill 4830 注:杀掉httpd的父进程;

[root@localhost ~]# ps -aux |grep httpd 注:查看httpd的其它子进程是否存在,httpd服务器是否仍在运行?

对于僵尸进程,可以用kill -9 来强制终止退出;

比如一个程序已经彻底死掉,如果kill 不加信号强度是没有办法退出,最好的办法就是加信号强度 -9 ,后面要接杀父进程;比如;

[root@localhost ~]# ps aux |grep gaim

beinan 5031 9.0 2.3 104996 17484 ? S 13:23 0:01 gaim

root 5036 0.0 0.0 5160 724 pts/3 S+ 13:24 0:00 grep gaim

[root@localhost ~]# pgrep -l gaim

5031 gaim

[root@localhost ~]# kill -9 5031

3.2 killall

killall 通过程序的名字,直接杀死所有进程,咱们简单说一下就行了。

用法:killall 正在运行的程序名

killall 也和ps或pgrep 结合使用,比较方便;通过ps或pgrep 来查看哪些程序在运行;

举例:

[root@localhost beinan]# pgrep -l gaim

2979 gaim

[root@localhost beinan]# killall gaim

3.3 pkill

pkill 和killall 应用方法差不多,也是直接杀死运行中的程序;如果您想杀掉单个进程,请用kill 来杀掉。

应用方法:

#pkill 正在运行的程序名

举例:

[root@localhost beinan]# pgrep -l gaim

2979 gaim

[root@localhost beinan]# pkill gaim

3.4 xkill

xkill 是在桌面用的杀死图形界面的程序。比如当firefox 出现崩溃不能退出时,点鼠标就能杀死firefox 。当xkill运行时出来和个人脑骨的图标,哪个图形程序崩溃一点就OK了。如果您想终止xkill ,就按右键取消;

xkill 调用方法:

[root@localhost ~]# xkill

2019-03-05 08:17:54 Ciellee 阅读数 270
  • 第2课时 Web服务器1

    1、Linux实战运维案例初级视频课程(RHCSA-RHCE-RHCA精讲)2、Linux实战运维案例中级视频课程(RHCSA-RHCE-RHCA精讲)3、Linux实战运维案例高级视频课程(RHCSA-RHCE-RHCA精讲)

    207人学习 秦冰
    免费试看

先把题目放出来:用Python 来实现 Linux grep 命令

grep命令分析:

  1. 输入: 无论输入字符串 还是 正则表达式都能搜索
  2. 搜索: 能够遍历目录及子目录下的所有文件 (我们此处暂时先简化为 遍历目录及子目录下的所有文本文件)
    ===> 此处需实现递归目录读取,以及 文本匹配成功后,将内容append在list中
  3. 结果: 搜索结果保存在 ./result/search_result.txt 中

第一步 生成数据文件

【Class 37】Python 实现Linux Grep 命(一)递归生成数据

第二步 代码实现

#! python3
# -*- coding: utf-8 -*-  
import re, os, time, shutil


# 在当前目录生成5个目录,每个目录中有不同名字的5个文件,树状循环两次
# 内容为 this is xxx文件名 \n  生成时间为当前时间: 2019/3/4-21:52:20  
def generate_file(dir_name_='.\\test_dir', file_depth=0 , dir_depth=0 , dir_cnt_=0):

    # 判断目录深度
    if dir_depth >= 3:
        dir_depth = 0
        return None
    dir_depth += 1
    # print(dir_name_)
    # 创建第一级目录
    if dir_name_=='.\\test_dir' and os.path.exists(dir_name_):
         shutil.rmtree(dir_name_)  # 递归删除目录
    os.makedirs(dir_name_)
    
    # 创建五个txt文件
    for k in range(5):
        file_name=''
        file_name = "%s\\Test_File_%d.txt"%(dir_name_, file_depth + k)
        # 创建5个文件
        fp = open(file_name, 'w')
        # 内容写入
        fp.write("This is %s !\nin directory:   %s\nCurrent Time is %s"%( os.path.basename(file_name),dir_name_,  time.strftime('%Y/%m/%d-%H:%M:%S')))
        fp.close()
 
    # 递归调用目录
    for k in range(5):
        # 文件命名起点增加5
        file_depth += 5
        # 目录名字计数计算
        dir_cnt = (dir_depth-1)*5 +  dir_cnt_*5 + k  if dir_depth > 1 else (dir_depth-1)*5 + k
        # 递归调用
        generate_file("%s\\sub_dir_%d_%d"%(dir_name_,dir_depth , dir_cnt), file_depth, dir_depth , k)


# 获得文件夹中所有的.txt 文件
def get_file_list(dir_path , txt_list=[]):
    # 判断dir_path 是否合法
    if not os.path.exists(dir_path):
        return None
    # 获取当前dir_path 下的所有文件
    dir_list = os.listdir(dir_path)
    
    if len(dir_list) >= 1:
        for file_txt in dir_list:
            #print("%s\\%s"%( dir_path ,file_txt))
            # 如果是文件,则将txt文件文件以绝对路径的形式保存在list中
            if os.path.isfile( "%s\\%s"%( dir_path ,file_txt) ):
                #if ".txt" in file_txt or ".TXT" in file_txt:
                if str(file_txt).endswith('.txt'):
                    txt_list.append( os.path.abspath(  "%s\\%s"%( dir_path ,file_txt) ) )

            #如果是目录            
            if os.path.isdir( "%s\\%s"%( dir_path ,file_txt) ):
                # 递归调用,继续遍历目录
                get_file_list("%s\\%s"%( dir_path ,file_txt), txt_list )
                
    else:
        print("no file in this %s"%dir_path)
        return None
    
    #print('获取文件列表:', txt_list)          
    return txt_list


# 传入文件路径,读取并匹配单个文件内容,判断式正则表达式 还是 单纯字符串
def get_file_matched_lines(rex_str, path):
    if not os.path.isfile(path):
        return "Path is not file !"

    # 初始化变量用于保存所有匹配的行
    match_list = []
    # 创建正则表达式对象
    rex_obj = re.compile(rex_str , re.VERBOSE)

    # 只读形式打开文件
    f_name_obj = open(path, 'r')  # 
    # 获取到该文件所有行
    f_lines = f_name_obj.readlines()
    # 及时关闭文件,避免造成文件占用
    f_name_obj.close()

    #逐行匹配
    for i in f_lines:
        if rex_obj.match(i):
            match_list.append( "第%d行:  %s" % (f_lines.index(i) , i) )  

    return match_list


# 代码主体
def find_grep_str(rex_str, path='.',save_file="search_result.txt"):
    # 初始化变量用于保存所有匹配的行
    match_list = []
    tmp = []

    # 获取当前目录下的所有txt 文件路径
    txt_list = get_file_list(path)

    #print(txt_list)
    # 读取所有文件内容,如果匹配则保存 第几行 和 行内容
    for f_name in txt_list:
        tmp = get_file_matched_lines(rex_str, f_name)
        print(tmp)
        if len(tmp) == 0:
            continue

        match_list.append("文件名:%s\n"%(f_name))
        match_list = match_list + tmp
        match_list.append("\n\n")
        
    # 保存文件
    if not os.path.exists(".\\result"):
        os.makedirs(".\\result")
    fp = open(".\\result\\%s"%save_file, 'w')
    for i in match_list:
        fp.write("%s"%i)
        
    fp.close()


if __name__ == "__main__":
    # 生成测试文件
    generate_file()

    # 字符串匹配
    str_rex = r'This\ is\ Test'
    find_grep_str(str_rex, save_file="str.txt")

    # 正则表达式匹配
    str_rex = r'(?=.*\d{4}).*'
    find_grep_str(str_rex, save_file="rex.txt")

结果如下:

字符串匹配结果 str.txt
文件名:C:\Users\Administrator\Desktop\tmp\new\test_dir\sub_dir_1_0\sub_dir_2_5\Test_File_10.txt
第0行:  This is Test_File_10.txt !

文件名:C:\Users\Administrator\Desktop\tmp\new\test_dir\sub_dir_1_0\sub_dir_2_5\Test_File_11.txt
第0行:  This is Test_File_11.txt !



正则表达式匹配结果 rex.txt
文件名:C:\Users\Administrator\Desktop\tmp\new\test_dir\sub_dir_1_0\sub_dir_2_5\Test_File_10.txt
第2行:  Current Time is 2019/03/05-22:04:32

文件名:C:\Users\Administrator\Desktop\tmp\new\test_dir\sub_dir_1_0\sub_dir_2_5\Test_File_11.txt
第2行:  Current Time is 2019/03/05-22:04:32
2018-03-23 00:02:11 baidu_20876831 阅读数 1372
  • 第2课时 Web服务器1

    1、Linux实战运维案例初级视频课程(RHCSA-RHCE-RHCA精讲)2、Linux实战运维案例中级视频课程(RHCSA-RHCE-RHCA精讲)3、Linux实战运维案例高级视频课程(RHCSA-RHCE-RHCA精讲)

    207人学习 秦冰
    免费试看

1,在某个路径下查文件。

在/etc下查找“*.log”的文件

find /etc -name “*.log”

2,扩展,列出某个路径下所有文件,包括子目录。

find /etc -name “*”

3,在某个路径下查找所有包含“hello abcserver”字符串的文件。

find /etc -name “*” | xargs grep “hello abcserver”

或者find /etc -name “*” | xargs grep “hello abcserver” > ./cqtest.txt

4,网上摘抄的几个和查找文件或文件内容相关的命令详说:

正则表达式
\分别表示单词的开始和结束
ex: \ 以T或者t开头,om结尾的单词
正则表达式的元字符集:
1) ^行首 /^love/ 以love开头的行;
2) $行尾 /love$/ 以love结尾的行;
3) .    /l..e/ 匹配所有这样的行,字母l后面紧跟任意两个字符然后是e的行
4) * 重复0次或者任意多次前面字符
5) [x-y] 字符范围
6) [^x-y] 排除字符范围
7) \ 转义字符
8) \ 界定单词的开头和结尾
9) \( \) 标记后面用到的匹配字符 \(love\)able \1er=loveable lover
10) x\{m,n\} 重复字符x至少m此,至多n次
—————————————————————————
—————————————————————————
grep家族
RE–regular expression; g: global; p: print
出了上面10种元字符集,grep还支持下面的RE
\w 字母或者数字
\W 非单词字符(标点符号)
+ 重复一个或者多个前面的字符
| 或 love(a:b)表示lovea或者lobeb
?单个字符
grep返回状态值($?) 0表示成功,1表示失败,2表示没有找到文件
rgrep递归访问目录树
—————————————————————————
ls -l |grep ^d 显示目录
grep -n -v -# -A# -B#
-i 不区分大小写
-n 显示匹配行和行号
-v只显示不匹配行
-#显示匹配行上下#行
-A#匹配行后面打印#行
-B#匹配行前面打印#行
-c 只输出匹配行的行数
-h 查询多文件的时候不显示匹配的文件名字
-l 查询多文件只显示匹配的文件名
-s 不显示错误信息
grep与正则表达式同用
grep “^[^abc]” *.f 提取行首不是abc的行
grep “[0-9]\{3\}[8]” *.f 提取类似xxx8的行,x表示任意数字
grep “a\{2\}” *.f 显示a至少出现两次的行,注意grep是以行处理单位的
grep -n “^$” file 列出空行的行号
-E参数,可以使用”与”和”或”模式
grep -E “abc | def” *.f 显示包含abc或者def的行
ex:
ls -l | grep “^$” 显示目录
ls -l | grep “^d” 显示文件
ls -l | grep “^d..x..x..x” 显示特定权限的目录
ps aux | grep “httpd” |grep -v “grep”
—————————————————————————
—————————————————————————
**使用find和xargs
1. find pathname -options [-print -exec -ok]
-optinos
1)-name:按照文件名查找
find ~ -name “*.txt” -print
find ~ -name “[a-z][0-9].txt” -print
2)-perm:按照权限查找文件
find ~ -perm 755 -print 查找权限为755的文件
find ~ -perm 007 -print 查找o位置上具有7权限的文件
find ~ -perm 4000 -print 查找具有suid的文件
3)-prune
不在当前目录下查找
4)-user和-nouser
find ~ -user zhao -print 查找文件属主是zhao的文件
find ~ -nouser -print 查找文件属主已经被删除的文件
5)-group和-nogroup
find ~ -group zhao -print 查找文件群组是zhao的文件
6)按照时间
find ~ -mtime -5 -print 文件更改时间在5天内的文件
find ~ -mtime +3 -print 文件更改时间在3天前的文件
find ~ -newer file1 -print 查找比文件file1新的文件
7)按照类型查找
find ~ -type d -print 查找所有目录
8)按照大小
find ~ -size +1000000C -print 查找文件大小大于1000000字节(1M)的文件
9)查找位于本文件系统里面的文件
find / -name “*.txt” -mount -print
-exec,-ok:find命令对于匹配文件执行该参数所给出shell命令,相应命令形式为: ‘command’ {} \;
-ok 在执行命令前要确认
find ~ -type f -exec ls -l {} \;
find / -name “*.log” -mtime +5 -ok rm {} \;
find . -name core -exec rm {} \;
使用-x dev参数
防止find搜索其他分区
find . -size 0 -exec rm {} \;
删除尺寸为0的文件
2. xargs与-exec功能类似
find ~ -type f | xargs ls -l
find / -name “*.log” -type f -print| xargs grep -i DB0
find . -type f |xargs grep -i “Mary”
在所有文件中检索字符串Mary
ls *~ |xargs rm -rf
删除所有以~结尾的文件
—————————————————————————
—————————————————————————
SED:
=====
sed [options] sedcommand inputfile >outputfile
sed不接触初始输入文件,对其不做修改,若想保存改动,重要将输出重定向到一个文件即可
a\: 当前行后面加入一行或者文本
c\: 用信文本替换本行的文本
d: 删除一行
D: 删除模板块的第一行
i\: 在当前行上面插入文本
h: 拷贝模板块的内容到内存缓冲区
H: 追加模板块的内容到内存缓冲区
g: 获得内存缓冲区内容,并替换当前模板中的文本
G: 获得内存缓冲区内容,并追加到当前模版块文本的后面
n: 读取下一个输入行,用下一个命令处理新行而不是第一个命令
N: 追加下一个输入行到模版块后面,并在二者间插入一个新行,改变当前行的号码
p: 打印模板块的行
P: 打印模板块的地一行
q: 退出sed
r file: 从file中读行
!: 表示后面的命令对所有没有选中的行起作用
s/re/strint/: 用string替换正则表达式re
=: 打印当前行号
#command: 把注释扩展到下一个换行符号前
l 打印匹配行,包括显示控制符号
**替换标记
g: 行内全部替换
p: 打印行
w: 把行写入一个文件
x: 互换模板块和缓冲区中的文本
y: 把一个字符翻译成另外一个字符
**sed中元字符可以使用正则表达式中所有的
新加:
& 保存搜索字符 s/love/**&**/ 用**love**代替love
**sed定位文本的方式
x 行号
x-y 从x行到y行
/patern/ 查询包括patern的行
x,y! 不包括指定x-y行号的行
ex:
sed ‘/Tom/d’ file
删除包含Tom的行;
sed ‘/Tom/!d’ file
删除所有不包含Tom的行;
sed -n /north/p’ file
打印包含north的行;
sed ‘3d’ file
删除第三行;
sed ’3,$d’ file
删除第三行到最后一行;
sed ‘$d’ file
删除最后一行;
sed ‘/north/d’ file
删除包含north的行;
sed -n ‘s/west/north/g’ file
替换所有west为north;
sed -n ‘s/^west/north/p’ file
一行的开头的west用north替换,并打印发生替换的行;
sed ‘s/[0-9][0-9]$/&.5/’ file
所有以两个数字结尾的行,最后两个数字被他们自己替换并附加.5;
sed -n ‘s/\(Mar\)got/\1ianne/p’ file
将Margot替换为Marianne,并打印发生替换的行;
sed ‘s#abc#ABC#g’ file
所有abc由ABC替换,(所有s后面紧跟的字符都被认为是新的分隔符);
sed ‘/west/,/east/p’ file
打印包含west行和包含east行中间的所有行;
sed ’1,/east/s/$/**A**/’ file
地一行和包含east行之间的所有行的行尾加上字符串**A**;
sed -e ’1,3d’ -e ‘s/aa/bb/’ file
先删除1到3行,然后用bb替换aa;
sed ‘/Sam/r file1′ file
将文件file1中的内容附加在包含Sam的行后面;
sed ‘/Sam/w file1′ file
将还有Sam行写入文件file1中;
sed ‘/^north /a\new line second line’ file
所有以north加空格开头的行后面附加上两行文本,a\表示追加文本,\表示换行(tcsh中需要,bash中不需要);
sed ‘/^north/i\new line’ file
在行首为north的行前面插入一个新行;
sed ‘/norht/{n; s/aa/bb/;}’ file
首先匹配含有north的行,然后执行一组命令,n表示移到下一行,并用bb代替aa;
sed ’1,3g/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/’ file
将1到3行中的所有小写字母用大写字母替换;
sed ‘/Lewis/{s/Lewis/bbb;q;}’ file
首先找到匹配Lewis的行,然后用bbb代替Lewis,接着q退出seq;
sed -e ‘/north/h’ -e ‘$G’ file
首先找到包含norht的行,h拷贝到内存缓冲区,然后到文件随后一行($),G附加在最后一行后面;
sed -e ‘/we/{h;d;}’ -e ‘/ct/{G:}’ file
查找包含we的行,拷贝并且删除他,然后查找包含ct的行,将拷贝内容附加到他后面;
sed -e ‘/north/h’ -e ‘$g’ file
首先找到包含norht的行,h拷贝到内存缓冲区,然后到文件随后一行并覆盖他;
sed -n ‘l’ file
打印所有包含不能打印字符的行。
sed -n ‘/.*ing/p’ file
显示含有以ing结尾单词的行;
sed -n ‘/music/=’ file
打印含有music的行号;
sed ‘^$d’ file
删除空行
sed ‘s/^/abcd/g’ file
在行首填加abcd
sed ‘s/$/abcd/g’ file
在行尾填加abcd
sed ‘s/rm$/played &/g’ file
&表示在替换的时候保留被替换的词(rm–played rm)
sed ‘s/^M//g’ file
去掉行尾的^M (^M的输入,先按ctrl+v然后按enter即可即可)
—————————————————————————
—————————————————————————
gawk程序:
awk [-F 域分隔符] ‘commands’ inputfile
awk执行时,其域标志符为$1,$2,$3………$n,$0表示所有的域
awk -v var=value 赋值给一个用户定义的变量
awk ‘pattern’ file
awk ‘{action}’ file
awk ‘pattern {action}’ file
ex:
awk ‘{print $0}’ file
打印所有的域
awk ‘/Mary/’ file
打印包含file中包含Mary的行;
awk ‘{print $1}’ file
打印文件的第一列(第一个域);
awk ‘/Mary/ {print $1,$2}’ file
打印文件file包含Mary的行的第一和第二个域;
df | awk ‘S4>75000′
打印可用空间大于75000的文件系统
date | awk ‘{print ” month:”, $2, “\n year:” $6}’
格式化date的输出;
awk ‘BEGIN{OFMT=”%.2f”; print 1.25463}’
指定数字输出格式,小数点后面保留两位有效数(1.25);
awk ‘/[ab]cdef/’ file
打印匹配acdef或者bcdef的行;
awk ‘{print NR, $0}’ file
awk ‘{print $0, NR}’ file
NR当前记录数,每处理一个记录NR就加1
上面的命令相当于在每一行后面加上一个行号;
NF则记录每一行的域的个数;
awk -F ‘[ :\t]‘ ‘{print $0}’ file
指定域分隔符为空格、:或者tab
awk ‘/^[A-Z][a-z]+/’ file
打印所有以一个大写字母开头,然后是一个或者多个小写字母的行;
awk ‘$1~/[Bb]ill/’ file
第一个域匹配Bill或者bill的行;
awk ‘$1!~/ly$/’ file
第一个域末尾不是ly的行;
awk ‘/^(No|no)/’ file
打印行首为No或者no的行;
awk ‘BEGIN {print “file head \n”} {print $1 \t $4}’ file
awk ‘BEGIN {print “file head \n”} {print $1 \t $4}’ file |tee out.file
打印文件的时候附加一个文件头
awk ‘BEGIN {print “file head \n”} {print $1 \t $4} END {print “end of file”}’ file
打印文件的时候附加一个文件头和文件尾
awk中使用正则表达式
awk ‘{if($1~/hello/) print $0}’ file
如果域1中包含hello,就打印所有的域
~//表示匹配正则表达式,!~//表示不匹配正则表达式
awk ‘{if($6,>=,==,!=,~,!~(匹配,不匹配)
awk ‘$3==5346′ file
第三个域等于5346,就打印出该行;
awk ‘$3>5000 {print $1}’ file
第三个域大于5000就打印该行第一个域
awk ‘{max={$1>$2}?$1:$2; print max}’ file
如果第一个域大于第二个域,max=$1否则=$2,打印最大值
awk ‘{print ($1==11?”high\t” $2:”low\t” $2)}’ file
&&逻辑和,||逻辑或,!逻辑非
awk ‘$2==$5 && $3>5′ file
awk ‘/Tom/,/Jary/’ file
Tom第一次出现和Jary第一次出现之间的所有行;
awk ‘/north/ {print $3+10}’ file
包含north行的地三个域加10;
awk ‘$3==”aa” {$2=”dd”; print $0}’ file
将地三个域为aa的行的第二域变成dd,并打印该行;
**awk编程:
使用变量
awk ‘$1~/Tom/ {wage=$2+$3; print wage}’ file
先扫描第一个域,如果匹配Tom,就将第二和第三域的总和赋值给变量wage并输出;
awk ‘BEGIN{FS=”:”; OFS=”\t”;ORS=”\n\n”}{print $0}’ file
处理文件前设置
域分隔符(FS)为(:)
输出域分隔(OFS)为(\t)
输出记录分隔符(ORS)为(\n\n)
awk ‘END{print “The number of record is:’ NR}’ file
处理完文件后执行END语句
输出总记录数
awk ‘/Mary/{count++} END{print “Mary was found” count “times”}’ file
计数文件中Mary出现的次数;
**awk输入输出重定向
awk ‘$4>=70 {print $1, $2 >”outfile”}’ file
结果重定向到文件outfile中
awk ‘BEGIN{“date” |getline d; print d}’
将date结果输给getline函数,并打印
(getline从标准输出,管道等获得输入)
awk ‘BEGIN{“date” |getline d; split(d,mon); print mon[1] mon[2]}’
将date结果输给getline函数,slpit将d分解成数组,打印数组第2个变量
**split函数:split(string,array,field seperator)
awk ‘BEGIN{while(“ls”|getline) print}’
依次输出ls的每一项
awk
‘BEGIN{print “what is your name?”; getline name 0) {lc++; print lc ” ” a}}’
awk ‘BEGIN{while(getline a 0) {lc++; print lc}}’
如果文件不存在,getline返回-1
到达文件尾返回0
读到一行返回1
读取文件/etc/passwd,计数行数
**awk控制语句
if语句:
awk ‘{if($6>50) print $1 “too high”}’ file
awk ‘{if($6>20 && $250}{x++; print x} else {y++;print y}’ file
awk ‘{if($1~/peter/){next} else {print}}’ file
如果第一个域包含peter,awk就忽略这一行,读取文件的下一行,脚本从头开始执行;
循环语句:
awk ‘{i=1; while(i file
cat -v file 显示文件,包括其中的控制符(-v)
cat -n file 为每一行编号
cat -b file 每个非空行编号
cat -T file 以^I显示tab
3.
管道 | 把一个命令的输出传递给另外一个命令为输入
ex:
ls | grep file.doc
查找文件file.doc
who | awk ‘{print $1 “\t” $2}’ 只显示用户名和所在终端
df -h | awk ‘{print $1}’ |grep -v “filesystem” (-v表示输出不包括filesystem的项目)
df -h | awk ‘{print $1}’ |grep -v “filesystem” |sed ‘s/\/dev\///g’ 显示设备的时候不显示/dev/
4.tee
who | tee who.txt 输出到屏幕的同时输出到文件
who | tee -a who.txt 附加在文件的后面
5.文件重定向
ls -l |grep ^d >file.out 所有目录名字重定向到一个文件
cat /etc/passwd | awk -F: ‘{print $1}’ |sort >a.out (-F:指定分隔符为:)
cat >file.out reboot
at> ctrl+D
3小时后reboot
3.
bc – 计算器
scale=3 设置小数点后数字为数
ibase=2 二进制运算
4.
ls -d dir
只显示目录而不显示其下面的文件。
5.
sync
更新superblock并把它写入硬盘
6.
scp user@host:/path/file1 user@host:/path/file
服务器间拷贝文件