grep 官方手册 awk 官方手册, awk 学习资料
grep 用于打印匹配指定模式的行。
grep 命令从输入文件中查找匹配到给定模式列表的行。发现匹配到的行后,默认情况下会复制这一行到标准输出流,也可以通过选项产生任何其他类型的输出。
grep 匹配文本时,对输入行长度没有限制(但受内存限制),并且可以匹配一行中的任意字符。如果输入文件的最后一个字节不是换行符,那么 grep 会提供一个。由于换行符也是模式列表的分隔符,因此无法在文本中匹配换行符。
选项可以有零个或多个。如果通过选项 -e pattern 或 -f file 指定了模式(pattern),命令中的模式是不可见的。input_file_names 也可以有零个或多个。
grep 带有一组丰富的选项,分别来自 POSIX 或 GNU 扩展。长选项都是 GNU 扩展的,即使对于 POSIX 规范中的选项也是如此。
但以下可能无法正常工作,因为管道 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:抑制关于不存在或不可读文件的错误消息。
当要输出多个前缀字段时,顺序始终是文件名,行号和字节偏移量,无法指定顺序。 - -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’这样的命令一起使用来处理任意文件名,甚至那些包含换行符的文件名。上下文行是匹配行附近的非匹配行。只有在使用以下选项之一时才会输出它们。无论如何设置这些选项,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 如何选择分隔符以在前缀字段和行内容之间打印的一些要点:
匹配行通常使用’:’作为前缀字段和实际行内容之间的分隔符。上下文(即非匹配行)行使用’-‘代替。当未指定上下文时,匹配行将被一个接一个地输出。指定上下文时,输入中相邻的行形成一个组,并且一个接一个地输出,而默认情况下,分隔符会出现在非相邻组之间。默认分隔符是’-‘行,它的存在和外观可以通过上述选项进行更改。每个组可能包含几个匹配行,当它们彼此足够靠近时,两个相邻的组连接并可合并成一个连续的组。--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:对于每个目录操作数,按照所有符号链接递归地读取并处理该目录中的所有文件。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’,表示终端默认背景上的粗体红色前景文字。
更多环境变量,参考 这里。
正常情况下,如果选择了一行,退出状态为 0,如果未选择行,则退出状态为 2,如果发生错误,退出状态为 2。但是,如果使用 -q 或 --quiet 或 --silent 选项并选择一行,即使发生错误,退出状态也为 0。其他 grep 实现可能会以大于 2 的状态退出。
参考 这里。
基于上一个命令的输出信息进行 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 # 匹配到两行不会输出任何信息,如果命令运行成功返回 0,失败则返回非 0 值。一般用于条件测试。
grep -q "test" 1.txtawk 是一种程序设计语言,语言风格类似 C 语言,设计目的是写那种一行搞定事情的脚本,常用于文本处理的脚本。包含常用的内置函数,支持用户函数和动态正则表达式,支持数组。
awk 是一种弱类型语言,不需要提前声明就可以使用变量,变量的类型转换也是隐含的,在不同的上下文中变量可能是不同类型。awk 的字符串连结操作不需要任何操作符,只要把需要连结的串并列写在一起即可。
awk 脚本通常由:BEGIN 语句块、能够使用模式匹配的通用语句块、END 语句块 3 部分组成,这三个部分都是可选的。脚本通常是被单引号或双引号中,所有指令用分号分隔。示例:
awk 'BEGIN{ i=0 } { i++ } END{ print i }' filename awk "BEGIN{ i=0 } { i++ } END{ print i }" filenameawk 中的 print 指令不带参数时打印当前行,参数可以是逗号分隔的列表。awk 的 print 中双引号被当作字符串连接符使用,例如:
# echo | awk '{a="a"; b="b"; print a,b}' a b # echo | awk '{a="a"; b="b"; print a","b}' a,bprintf 指令跟 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变量示例:
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两种方式向 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 200awk 脚本是由模式和操作组成。
语法:
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可以判断行内的某个字段是否满足条件,满足则打印数据。支持的运算符有:==,!=,>,<,>=,<=。
[root@VM_120_242_centos test]# echo -e 'abc ok\n1234\nxxx ok' | awk '$2=="ok"' abc ok xxx ok模式匹配时,可以将行内的某个字段使用正则表达式匹配。~ 表示开始模式匹配且打印匹配成功的行。
[root@VM_120_242_centos test]# echo -e 'abc ok\n1234\nxxx ok' | awk '$2 ~ /ok/' abc ok xxx ok语法:
awk 'BEGIN{ commands } { commands } END{ commands }' file工作流程:
执行 BEGIN{ commands } 语句块中的语句,BEGIN 关键字可以省略。从文件或标准输入(stdin)读取一行后执行 { commands } 语句块,然后读下一行并再次执行 { commands } 语句块,直到最后一行。当读至文件或输入流末尾时,执行 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操作位于大括号内,由一个或多个命令、函数、表达式组成,用换行符或分号分隔。模式匹配成功后,执行后面的操作。例如上面的 awk '/[0-9]/{a=$0}{printf a} ' 中的 {a=$0}{printf a} 就是操作。
从输入中每次获取一行输入。可以通过 while 循环,读完所有行。
将管道前命令输出的结果作为 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从处理的文件中读取输入。同样,如果没有 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 fineclose 函数可以用于关闭已经打开的文件或者管道,很少会用到。
上面例子中 getline 函数的第一种形式用到管道,我们可以用 close 函数把这个管道关闭 close("cat statement.txt")。
执行外部命令,例如:
[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/Linuxawk 的字符串连结操作不需要任何操作符,只要把需要连结的串并列写在一起即可。
[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处理文本经常使用数组。数组索引(下标)可以是数字和字符串在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。
length 函数是 awk 内置函数,用于求数组长度。
[root@VM_157_18_centos test]# awk 'BEGIN{ a[1]=123; a[2]="abc"; print length(a); }' 2awk 中的二维数组用法跟 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 = 9strftime日期和时间格式说明符:
格式描述%a星期几的缩写(Sun)%A星期几的完整写法(Sunday)%b月名的缩写(Oct)%B月名的完整写法(October)%c本地日期和时间%d十进制日期%D日期 08/20/99%e日期,如果只有一位会补上一个空格%H用十进制表示24小时格式的小时%I用十进制表示12小时格式的小时%j从1月1日起一年中的第几天%m十进制表示的月份%M十进制表示的分钟%p12小时表示法(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获取随机数示例:
[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());}' 76awk 的流程控制语句跟 C 语言中的类似。
示例:
[root@VM_157_18_centos test]# awk 'BEGIN{ score=60; if (socre > 60) { print "good"; } else if (score <= 60) { print "danger"; } else { print "hehe"; } }' dangerawk 中支持 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 123awk 就像是 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转载于:https://www.cnblogs.com/kika/p/10851672.html
相关资源:数据结构—成绩单生成器