一、文本处理 1、tr 替换或删除字符;将STRING1替换为STRING2;替换的时候对位(按照每一位进行)替换; 如果STRING1字符数多于STRING2,则STRING2的最后一位字符作为STRING1剩余的替换符号; tr工具既需要标准输入,也有标准输出; 格式: tr [OPTION] "STRING1" ["STRING2"] 选项: -c|-C # 取指定字符的反集 -d # 删除字符STRING1 -s # 将连续重复的字符以单独字符表示 -t # 严格按照STRING1的格式进行替换 用法: 大小写转换:tr 'a-z' 'A-Z' 除abc字符,删除其余所有字符:tr -dc 'abc' 2、cut 按列处理文本 选项: -d # 指定分割符号。默认空格作为分割符。例如:-d: | -d ':' -f # 指定取第几段。例如:-f4 | -f 4 | -f 1,3 | -f 1-3 | -f 1-4,5 -c # 按字符取出,可以是一个范围。例如:-c 5- | -c 5-12 -output-delimiter=STRING # 指定输出时的分割符 示例: # 取出磁盘分区利用率 df | cut -c 44-47 df | tr -s ' ' '%' | cut -d '%' -f 5 # 取IP地址 ifconfig ens33 | head -2 | tail -1 | cut -d '0' -f '1' | cut -dn -f2 | cut -dt -f2 | cut -d ' ' -f 2 ifconfig eth0 | head -2 | tail -1 | cut -d: -f2 | cut -dB -f1 | cut -d ' ' -f 1 | cat -A ifconfig ens33 | head -2 | tail -1 | tr -s ' ' | cut -d ' ' -f 3 | cat -A # web日志切割分析 cat access_log | cut -d ' ' -f 1 | sort -u 3、paste 将两个文件的同一行号的行横向的合并为一行,默认合并后tab键作为分割符号 选项: -d # 指定分割符号 -s # 将每一个文件的内容合并成一行,每个文件的内容显示为一行 4、sort sort默认按每行的第一个字符排序,字母排序。 选项: -u # 将重复的行仅显示一次 -n # 按数字进行排序 -t # 指定分割符 -k # 指定对那一段进行排序 -r # 倒序排列 -f # 忽略大小写 示例: # 将/etc/passwd中UID进行排序 cat sortpasswd.txt | cut -d ":" -f "1,3" # 将/etc/passwd中UID进行倒序排序 cat /etc/passwd | sort -n -r -t ':' -k 3 # 取出分区利用率,并进行排序 df | tr -s " " | cut -d ' ' -f 1,5 | sort -t " " -k 2 -nr 注:可以通过[重定向]的方式将分割后的文件组成成一个文件 5、uniq 从输入中删除前后相领重复的行 选项: -c # 统计重复的行的行数(直接相领的行才算重复的行) -d # 只显示重复过的行,即显示出重复过的行(每个重复过的行显示一次) -D # 将有重复的行全部列出来,不重复的行不显示 -u # 仅显示没有重复过的行 示例: # 分析web日志,统计每个IP的访问次数 cat access_log | cut -d ' ' -f 1 | sort | uniq -c | sort -nr # 统计账号登录次数 last | cut -d ' ' -f 1 | sort | uniq -c 6、expand 将tab键转换为空格 选项: -t # 指定tab键是几个空格,默认是8个空格 7、split 将文档内容分割,然后分别保存 选项: -l # 按行分割,指定多少行输出为一个文件 -b # 按字节输出,指定每个文件的字节数 -d # 表示用数字作为分割后的文件后缀 -a # 指定分割后的文件名的后缀的长度 示例: # 将一个大文件按M分来 split -b 1000000 big.file -d -a 3 big.file 8、diff 以行为单位对两个文档进行比对。一般用在ASCII纯文本文档。命令的输出叫"补丁" 选项: -B # 忽略空白行 -i # 忽略大小写 -u # 显示更详细的不同之处的信息 示例: diff /etc/passwd /etc/passwd.bak 9、patch 两个有差异的文档,根据其中一个恢复其中一个,可用于更新和恢复。 选项: -b # 恢复或更新之前将源文件备份,备份文件后缀为.orig。不加-b选项,会将原文件覆盖 示例: 建立补丁文件:diff -u 1.txt 2.txt > diff.txt 修复原文档:patch -b 1.txt diff.txt (如果有一个文件删除或者损坏,则可以根据补丁文件修复) ============================================================================================================================================== 二、文本查看 1、cat 查看文件信息 选项: -n # 显示行号 -b # 忽略空行,不显示空行的行号 -E # 显示结束符号 -s # 压缩连续的空行为一行 -A # 显示所有控制符号 -T # 显示控制tab控制字符 2、tac 反向反向显示文本 3、less 可以分页查看,支持搜索 4、more 显示退出提示 5、head 显示文本头几行,默认显示头10行。head 需要标准输入 选项: -n N # 显示前N行 -c N # 显示前N个字节 示例: head -4 FILENAME # 显示头4行 6、tail 显示文本后N行,head 需要标准输入 选项: -n N # 显示后N行 -c N # 显示后N个字节 -f # 跟踪文件新追加的内容,常用于日志监控 示例: tail -n 2 -f /path/filename # 一直显示文本中的最后两行 cat /var/log/message | head -1000 | tail -1 # 显示第1000行 7、nl 显示行号 8、rev 同一行按字符反向显示 ============================================================================================================================================== 三、文本分析 1、wc wort count,文本统计工具 选项: -l # 行 -c # 字节 -m # 字符数 -w # 单词数 示例: wc FILENAME # 分别显示行、词、字节数 注意:wc命令通过对来自管道的文本进行统计时不会显示文件名,只有统计的数字 ================================================================================================================================ 四、grep grep(globally search a regular expression and print),文本搜索工具,根据指定的模式对目标按行进行匹配并打印。 grep文本处理工具按行对文本进行处理。 选项: --color-auto# 匹配的字符有颜色显示 -v # 反向选择,即将没有匹配到的行显示出来 -i # 忽略大小写 -e # 逻辑“或”,包含字符串A或者字符B串 -n # 输出时显示符合的行所在的行数 -c # 计算在文本中符合匹配的字符的行数 -o # 只显示被模式匹配的字符串,每个字符串占一行 -A # 后面跟一个数字,表示取出匹配行后显示前[数字]行 -B # 后面跟一个数字,表示取出匹配行后显示后[数字]行 -C # 后面跟一个数字,表示取出匹配行后显示前和后[数字]行 -F # 相当于fgrep,不支持正则表达式 -w # 匹配一个完整的单词字符串 -E # 使用扩展正则表达式,相当于egrep 示例: # 取出ip地址 ifconfig ens33 | grep -w inet | tr -s ' '| cut -d ' ' -f 3 # 取分区利用率最大值 df -h | grep /dev/sd | sort -t '/' -k 2 | tr -s ' ' '%' | cut -d '%' -f 5 | head -1 =============================================================================================================================== 五、正则表达式 1、通配符 * # 任意长度字符串 ? # 匹配某一个字符(包括汉字,一个汉字是一个字符) [ ] # 匹配其中的任意一个字符 [^] # 排除匹配其中的字符 [0-9] # 范围 2、通配符和正则表达式的区别: 通配符通常用来用作文件名匹配,是shell解释器赋予的特殊含义。 正则表达式用来匹配字符串,在支持正则表达式的工具中可以使用。 3、正则表达式(Regular Expression) 正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。一个正则表达式通常被称为一个模式(pattern), 为用来描述或者匹配一系列匹配某个句法规则的字符串。 正则表达式有基本正则表达式和扩展正则表达式。 基本正则表达式:Basic REGEXP 扩展正则表达式:Extended REGEXp 4、元字符 字符匹配: [:alnum:] # 代表英文大小写字符及数字,亦即 0-9, A-Z, a-z [:alpha:] # 代表任何英文大小写字符,亦即 A-Z, a-z [:blank:] # 代表空白键与 [Tab] 按键两者 [:cntrl:] # 代表键盘上面的控制按键,亦即包括 CR, LF, Tab, Del.. 等等 [:digit:] # 代表数字而已,亦即 0-9 [:graph:] # 除了空白字符 (空白键与 [Tab] 按键) 外的其他所有按键 [:lower:] # 代表小写字符,亦即 a-z [:print:] # 代表任何可以被打印出来的字符 [:punct:] # 代表标点符号 (punctuation symbol),亦即:" ' ? ! ; : # $... [:upper:] # 代表大写字符,亦即 A-Z [:space:] # 任何会产生空白的字符,包括空白键, [Tab], CR 等等 [:xdigit:] # 代表 16 进位的数字类型,因此包括: 0-9, A-F, a-f 的数字与字符 [] # 匹配指定范围的任意单个字符。[abcd] [a-b] [^] # 除指定范围的任意单个字符 . # 任意单个字符 匹配次数: * # 表示匹配前面的字符[任意次],包括0次。即前面的字符重复任意次。grep默认是贪婪模式,尽可能多的向后匹配 .* # 任意长度的任意字符 \? # 匹配前面的字符一次或零次 \+ # 匹配其前面的字符至少一次 \{n\} # 匹配前面的字符n次 \{n,\} # 匹配前面的字符n次以上,包含n次 \{n,m\} # 出现n,m次,包括n和m次 \{,m\} # 匹配m次以下,包括m次 ^[[:space:]]*$ # 空白行 位置锚定: ^ # 行首锚定,用于pattern的最左侧 $ # 行尾锚定,用于pattern的最右侧 \<或者\b # 锚定词首,[除字母、数字、下划线外都可以作为单词的边界] \>或者\b # 词尾锚定 \<\> # 锚定一个单词 分组: \(\) # 前面的一个整体例如单词,可以向后重复 \1 # 引用前面分组的内容。还可以有\1(引用第一个分组的内容) \3(引用第三个分组的内容) \4 逻辑: string\|string2 # 或的关系,匹配 示例: # 查找/etc/passwd中以 r开头,t结尾,包含中间有任意两个字符的字符串的行 grep r..t /etc/passwd # 查找以a开头,后面跟有a或b或c的字符 grep a[abc] /etc/passwd # 匹配以r开头,t结尾,中间有任意个o字符的字符串 grep r.*t /etc/passwd # 匹配以r开头,t结尾,中间有至少2个o字符的字符串 grep r...*t /etc/passwd # 匹配以g开头,gle结尾,中间出现1次或者2次o字符的字符串 grep "ro\?gle" filename # 匹配以g开头,gle结尾,中间至少出现一次o字符的字符串 grep "go\+gle" filename # 匹配以g开头,gle结尾,中间o字符出现5次 grep "go\{5\}gle" filename # 匹配以g开头,gle结尾,中间o字符出现5次以上 grep "go\{5,\}gle" filename # 匹配以g开头,gle结尾,中间o字符出现最少2次,最多5次 grep "go\{2,5\}gle" filename # 匹配以g开头,gle结尾,中间o字符出现5次以下 grep "go\{,5\}gle" filename # 查找所有使用bash的用户 grep "bash$" /etc/passwd # 不显示空行 grep -v "^$" filename # 不显示/etc/fatab文件中的所有注释内容和空行 cat /etc/fstab | grep -v "^#" | grep -v "^$" # 去掉空行和以空格开头空行 cat 1.file | grep -v "^[[:space:]]*$" # 取出以xue开头的单词 cat 2.file | grep "\<xue" # 取出单词 grep -o "\<[[:alnum:]_]*\>" # 前面的单词出现两次 grep -o "\(god\)\{2\}" 5、注意 1、当需要匹配的字符是元字符时,需要转义之后进行匹配。例如:匹配 . 则 "\." 2、当匹配 \ 符号时,需要使用单引号并转义 '\\' 3、通配符中[a-z]范围中包括大写字母,在正则表达式中[a-z]只有小写字母 4、分组引用中,\(\)之后使用\1引用的是前面匹配的结果,而不是匹配模式 5、分组特殊情况 \(string1\+\(string2\)*\) \1:string1\+\(string2\)* \2:string2 6、正则表达式匹配 邮箱:[[:alnum:]_-.]\+@[[:alnum:]_-]\+\.[[:alnum:]_-]\+ ============================================================================================================================================== 六、扩展正则表达式 字符匹配:(和基本正则表达式含义相同) . # 任意单个字符 [] # 指定范围字符 [^(bash)]$ # 非bash结尾的行 [^] # 反向选择,即将没有匹配到的行显示出来 次数匹配: * # 匹配前面字符任意次 ? # 匹配0或1次 + # 1次或多次 {m} # 匹配前面的字符m次 {m,n} # 匹配前面的字符至少m次,至多n次 位置锚定: ^ $ \<或者\b \>或者\b 分组: () # 分组。引用\1 \2 扩展: a|b # a或者b C|cat # C或cat (C|c)at # C或者c ============================================================================================================================================== 七、sed 1、基本原理: Stream EDitor。流编辑器。sed 流编辑器,源自英语"stream editor"的缩写。能够实现文本编辑。 sed并不直接处理文本本身,而逐行读取,把行读取到内存中,在内存中完成编辑,把这段内存称为:模式空间。 sed在处理文件的时候,[逐行](循环)读进内存空间,进行模式匹配,然后对行进行编辑,处理结束后,把模式空间内的 内容结果输出到屏幕。 默认会将经过模式空间的行都打印到屏幕。 2、使用格式: sed [options] 'AddressCommand' inputfile …… Address: 1、startline,endline # 例如:1,100 行 2、/RegExp/ # 正则表达式,被模式匹配到的所有行。 例如:以root开头的行 /^root/ 3、/pattern1/,/pattern2/# 第一次被模式1匹配到的行至第一次被模式2匹配到的行结束,这中间的所有行 4、LineNumber # 指定行。$:最后一行 5、StartLine,+N # 从StartLine开始,向后的N行 6、3~N # 步进。3~2表示从第三行开始,每2行取一行。打印偶数行 sed -n '2~2p' Command: d # 删除符合条件的行 p # 显示[符合条件]或者[处理过]的行 a \"string" # 在指定行[后面]追加新行,内容为 string ,不加引号也可以,支持使用\n实现多行插入 示例添加两行:sed '/^\/ /a \# hello world \n #hello linux' /etc/fstab i \"string" # 在指定行[前面]追加新行,内容为 string。支持使用\n实现多行插入 r filename # 将指定的文件的内容添加至符合条件行处 示例:将/etc/issue的文件添加到/etc/fstab文件的第二行 sed '2r /etc/issue' /etc/fstab c \"string" # 替换符合条件的行 cat /etc/fstab | sed '/^UUID/ c \xuejinwei' w filename #将指定范围内的内容匹配的行另存至指定的文件 示例:将/etc/fstab文件内匹配的行保存到/tmp/oot.tx sed -n '/oot/w /tmp/oot.txt' /etc/fstab = # 显示匹配到的行的行号 sed '/^UUID/=' /etc/fstab ! # 取反条件。 sed '/^UUID/!d' /etc/fstab s/pattern/string/修饰符 # 查找并替换。默认替换每一行第一次被匹配到的字符串。(先匹配后替换) 示例:将/etc/fstab行开头“/”换成“#” sed 's/^\//#/' /etc/fstab 1、如果要将每一行匹配到的所有字符串都替换则需要加修饰符 修饰符: g:全局替换 i:忽略大小写 2、s 用法中有分隔符'/'也可以用/#' '@' 代替。 3、s 操作还可以后向引用替换:sed 's#l..e#&r#g' /sed.txt 或者 sed 's#\(l..e\)#\1#g' /sed.txt 4、引用一个词的一部分: 示例:将hello,like hi,my love中的like、love首字母l换成L sed 's#l\(..e\)#L\1g' /sed.txt option: -n # 静默模式,不将模式空间中的内容输出到屏幕 -i # 直接修改原文件 -i.bak # 修改原文件前将文件先备份一个后缀为.bak的文件 -e # 可以执行多个'AddressCommand'步骤,每一个-e面跟一个步骤 sed -e ' ' -e ' ' -f # 把每一个sed执行命令保存到文件当中,然后读取文件中的内容即可 sed -f /path/to/scripts filename -r # 表示使用扩展正则表达式,默认使用的是基本正则表达式 3、高级编辑命令 (多个编辑命令用分号隔开,例如sed -n 'n;p') h # 把模式空间中的内容覆盖到保持空间中 H # 把模式空间中的内容追加到保持空间中 g # 从保持空间中取出数据覆盖模式空间 G # 从保持空间取出数据追加到模式空间 x # 将模式空间中的内容和保持空间中的内容互换 n # 读取匹配到行的下一行到模式空间 N # 追加读取匹配到行的下一行到模式空间 d # 删除模式空间中的行 D # 删除模式空间中的所有行 P # 打印模式 空间开端至\n 内容 *********************************************************************************************************** (按行循环执行) P 打印模式空间开端至\n内容,并追加到默认输出之前(模式空间中可能存在多行的情况) h 把 [模式空间] 中的内容 [覆盖] 至 [保持空间] 中 H 把 [模式空间] 中的内容 [追加] 至 [保持空间] 中 g 从 [保持空间] 取出数据 [覆盖] 至 [模式空间] G 从保持空间取出内容追加至模式空间 x 把模式空间中的内容与保持空间中的内容进行互换 n 读取 [匹配] 到的行的下一行 [覆盖] 至 [模式空间] N 读取匹配到的行的下一行 追加 至模式空间 d 删除模式空间中的行 D 如果模式空间包含换行符,则删除第一行,并不会读取新的输入行,而使用合成的模式空间 重新启动循环。如果 模式空间不包含换行符,则会像发出d命令那样启动正常的新 循环 ************************************************************************************************************ 示例: 1、例如读取偶数行 sed -n 'n;p' FILENAME 2、逆向显示文本 sed '1!G;h;$!d' FILENAME 3、取文件最后两行 sed '$!N;$!D' FILENAME 4、取文件最后一行 sed '$!d' FILENAME 5、每一行行后加一个空白行 sed 'G' FILENAME 6、删除空白行,并在每一行后添加一个空白行 sed '/^$/d;G' FILENAME 7、删除奇数行 sed 'n;d' FILENAME 8、打印最后一行 sed -n '1!G;h;$p' FILENAME seq 1 10 | sed 'N;D' 4:练习 1、去掉文件所有行的行首的空白字符 sed 's#[[:space:]]*##' sed1.txt 2、将文本中字符串中“ id:3:initdefault ”中的数字“ 3 ”换成 “ 5 ” sed 's#\(id:\)[0-9]\(:initdefault\)#\15\2#' sed1.txt 3、删除/etc/inittab文件中,以“ # ”开头,且其后没有任何字符的行 sed '/^#$/d' sed1.txt 4、删除/etc/inittab文件中行首的"#"字符 sed 's@^#@@' sed1.txt 5、删除/etc/inittab文件中的"#"及其后面的空白字符,且"#"后必须要有空白字符 sed 's@^#[[:space:]]\{1,\}@@' sed2.txt 6、删除某文件中以空白字符后面跟"#"字符类行中的开头的空白字符和"#" sed 's@^[[:space:]]\{1,\}#@@' sed2.txt 7、取出文件的路径 echo "/root/works/sh" | sed -r 's@^(/.*/)[^/]+/?@\1@g' 8、取出路径中的文件名(基名) echo "/root/works/sh" | sed -r 's@^/.*/([^/]+)/?@\1@g' ========================================================================================================================================= 1、awk awk是一个文本处理工具,可以对数据进行处理。awk可以进行正则表达式匹配、样式装入、流控制、数学运算符、进程控制语句甚至于内 置的变量和函数。 2、处理过程 AWK是一种处理文本文件的语言。它将文件作为记录序列处理。在一般情况下,文件内容的每行都是一个记录。每行内容都会被分割成一系列 的域,因此,我们可以认为一行的第一个词为第一个域,第二个词为第二个,以此类推。AWK程序是由一些处理特定模式的语句块构成的。AWK 一次可以读取一个输入行。对每个输入行,AWK解释器会判断它是否符合程序中出现的各个模式,并执行符合的模式所对应的动作。 将处理的内容进行过滤格式化然后输出。 awk对文本进行处理时,循环对每一行进行处理,然后对行进行切片,分别将切片赋值给awk的内置变量$1、$2...。 3、使用格式 awk [option] 'BEGING{}/pattern/{action}END{}' FILENAME option: -F # 指定分割符,默认是空格作为分割符 -v VARNAME=var # 自定义变量。例如 awk -v num1=10 -v num2=30 'BEGING{print num1+num2}' 也可以在 BEGIN 中定义变量。例如 awk 'BEGING{num1=10;num2=20}{print num1+num2}' 变量应怎讯先定义后使用的原则 -f FILE_NAME # 从文件中读取 awk 脚本 scripts: '/pattern/{action}' pattern: 地址定界: /pattern1/,/pattern2/ /pattern/ # 模式匹配(正则表达式匹配行) /expression/ # 表达式,> >= < <= == != ~ 注:~为模式匹配 !/pattern/ # 取反 '(NR>10&&NR<20)' # 行号 action: # 默认操作为 print 表达式 控制语句 组合语句 输入语句 输出语句 BEGING{}: 处理前(遍历操作之前)进行的操作 # 示例:添加提示字段 awk -F : 'BEGIN{print "UserName: "}$3>=1000{print $1,$3,$7}' /etc/passwd END{} # 结尾后(遍历操作之后)添加信息 awk -F : 'BEGIN{print "UserName\n==================="}$3>=1000{print $1,$3,$7}END{print "===================\n2 User."}' /etc/passwd 4、awk 四种分割符 FS,输入字段分割符(field separator) # 默认是空格为分割符 RS,输入行分割符(Record separator) # 默认是换行符 \n OFS,输出字段分割符(Output Filed Separator) # 默认是空格符 ORS,输出行分割符(Output Row Separator) # 默认是换行符作为分割符 5、awk中内置变量 $0 # 整行的所有字段 NF # Number of Fileld,行的最后一个字段。NF 表示字段的总个数 $NF # Number of Fileld,行的最后一个字段内容。$(NF-2) 表示导出第二个字段 FS # [输入字段分割符],可以对默认的空格分割符进行重新赋值 RS # [输入行分割符] OFS # [输出字段分割符],默认是空格 ORS # [输出行分割符],输出时用指定符号作为分割符号 NR # The Number of input records,总共处理的行记录个数。如果有多个文件,则一起计数 例如:awk '{print FNR,$0}' /etc/passwd /etc/fstab 是对两个文件的行分别进行计数 FNR # 对单个文件分别进行计数, FILENAME # 处理的文件名称,保存文件名的变量 ARGC # awk命令的参数个数。 awk 后面跟的以空格分割的字符串都是参数 ARGV # 是一个数组。ARGV[0]、ARGV[1],分别保存awk命令和参数.... (awk 也属于参数) 注:显示变量本身时,print 输出不能添加 $ 符号 6、awk 操作符 1、算数操作符 ** # 平方运算 * # 乘法 % # 取模运算 / # 除法 awk 'BEGING{print N+N}' # 支持浮点运算 2、赋值操作符 == # 当有模式匹配等号的时候,要用/[=]/替代,否则会被语法误认为是赋值 例如 $0 == /root/ += -= *= /= ^= **= # 平方运算赋值 ++ -- 3、布尔值 任何非0值或非空字符串为真,否则为假 4、比较操作符 < > ... <= != ~ # 字符串匹配(包含) 示例: $1 !~ /root/ !~ # 字符串匹配取反 5、逻辑关系 && || ! 7、条件判断 selector?if-true-exp:if-false-exp if selector; then if-true-exp else if-false-exp fi a=3 b=4 a>b?a is max:b ia max 语法格式: if (condition) {then-body} else {[ else-body ]} if (condition1) {then-body} else if(condition2) {[ else-body ]} else (condition3) 示例: # 比较两个数字大小 awk -v num1=30 -v num2=35 'BEGIN{num1>num2?max=num1:max=num2;print max}' # 判断 /etc/passwd 中的普通用户和root用户,并显示 awk -F : '{if ($3=0) {printf "%-17s %s\n",$1,"administrator."} else {printf "%-17s %s\n",$1,"general user."}}' /etc/passwd # 统计UID大于500的用户个数 awk -F : -v sum=0 '{if ($3>=500) {sum++}}END{print sum}' /etc/passwd 8、循环 1、while 语法格式: while (condition) {statement1; statment2; ...} # 和C语言的语句格式几乎一样 2、do-while 语法格式: do {statement1, statement2, ...} while (condition) 3、for 语法格式: for (variable assignment; condition; iteration process) { statement1, statement2, ...} 示例: awk -F: '{for(i=1;i<=3;i++) print $i}' /etc/passwd awk -F: '{for(i=1;i<=NF;i++) { if (length($i)>=4) {print $i}}}' /etc/passwd 注:length 是 awk 内建函数,计算字符串的长度 awk 数组 (循环遍历数组) for 循环 1、awk 'BEGIN{a[0]="xue";a[1]="jin";a[2]="wei";for (i=0;i<=2;i++) {print a[i]} }' 2、awk -F: '$NF!~/^$/{BASH[$NF]++}END{for(A in BASH){printf "%15s:%i\n",A,BASH[A]}}' /etc/passwd awk -F: '$NF!~/^$/{print $NF}' /etc/passwd # 表示最后一个字段不为空 A in BASH # 表示遍历此数组(关联数组)的下标 3、统计当前TCP连接状态的个数 netstat -tn | awk '/^tcp/{s[$NF]++}END{for (A in s) {printf "%15s %d\n",A,s[A]}}' 4、统计访问状态码出现的次数 awk '{ stcode[$9]++ }END{ for (A in stcode) {printf "%-5s %d\n",A,stcode[A]}}' access_log 10、格式化输出 格式: printf "%d\n",num_var 格式化符号: %c # ASCII码 %d # 十进制数 %e|%E # 科学计数法 %f # 显示浮点数 %g|%G # 以科学计数法格式或浮点数格式显示数值 %s # 显示字符串 %u # 显示无符号整数 %% # 显示百分号本身 修饰符: N # 指定显示宽度 - # 左对齐(默认情况是右对齐) + # 显示数值符号 示例: %3.1f 表示打印浮点数格式,显示宽度为3,小数点后1位 11、awk 处理后输出重定向 print $0 > filename print $0 >> filename print $0 | filename 12、函数 function_name(pra1,pra2) 13、示例 # 显示 /etc/passwd root开头的行的第一个字段 awk -F : '/^root\>/{print $0}' /etc/passwd # 显示文件磁盘使用情况 df | awk '/^\/dev\//{print $5}' # 取出 /etc/passwd ID号大于1000的用户名 awk -F : '$3>=1000{print $0}' /etc/passwd # 取出用户的登录 shell 为 bash 的用户 awk -F : '/bash$/{print $0}' /etc/passwd 注:使用模式匹配 awk -F : '$7~/bash$/{print $0}' /etc/passwd # 重新对分割符进行赋值 awk 'BEGIN{FS=":"}$3>=1000{print $1,$6,$7'} /etc/passwd # 显示 /etc/passwd 第一个字段和最后一个字段,第一个字段左对齐,第二个字段右对齐 awk 'BEGIN{FS=":"}{printf "%17s %5d %s\n",$1,$3,$NF}' /etc/passwd 14、case语句 语法格式:switch (expression) { case VALUE or /REGEXP/: statement1, statement2,... default: statement1, ...} 示例: awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i%2==0)continue;sum+=i}print sum}' awk 'BEGIN{sum=0;for(i=1;i<=100;i++){if(i==66)break;sum+=i}print sum}' 15、break 和 continue 使用于循环或 case 语句 16、next 提前结束对本行的文本处理,并接着处理下一行 示例: # 显示IP号为奇数的用户 awk -F : '{if ($3%2==0) {next} else {printf "%-18s %d\n",$1,$3} }' /etc/passwd 17、awk 内置函数 1、split 语法:split(string,array,"fileldsep") 功能:将 string 表示的字符串以 fileldsep 为分割符进行分割,并将分割后的结果保存至 array 为名的数组中,数组下标从1开始 示例: # 统计 tcp IP地址连接个数 netstat -tun | awk '{ split($5,Faddr,":");IP[Faddr[2]]++}END{ for (A in IP) {printf "%-7s %d\n",A,IP[A]}}' # 显示当前系统磁盘空间占用了大于百分八十的磁盘 df | awk '/^\/dev\/sd/{split($5,disk,"%");if(disk[1]>1) {printf "%s %d%%\n",$1,$5}}' 2、length(string) 语法:length(string) 功能:返回字符串的长度 示例: # 统计文件每一行的字符个数 cat /etc/fstab | awk '{print length($0)}' # 统计文件总共的字符个数 cat /etc/fstab | awk -v sum=0 '{sum=sum+length($0)}END{print sum}' 3、substr 语法:substr(string, start [, length]) 功能:取string字符串中的子串,从start开始,取length个;start从1开始计数; 示例: 4、system(command) 功能:执行系统command并将结果返回至awk命令 5、systime() 功能:取系统当前时间 6、tolower(s) 功能:将s中的所有字母转为小写 7、toupper(s) 功能:将s中的所有字母转为大写 8、rand() 功能:返回0和1之间一个随机数 awk 'BEGIN{srand(); for (i=1;i<=10;i++)print int(rand()*100) }' srand() # 生成随机数种子 int() # 取整 9、sub(r,s,[t]) 功能:对 t 字符串进行搜索 r 表示的模式匹配的内容,并将第一个匹配的内容替换为s 示例:echo "2008:08:08 08:08:08" | awk 'sub(/:/,"-",$1)' 结果:2008-08:08 08:08:08 10、gsub(r,s,[t]) 功能:对 t 字符串进行搜索 r 表示的模式匹配的内容,并全部替换为 s 所表示的内容 示例:echo "2008:08:08 08:08:08" | awk 'gsub(/:/,"-",$0)' 18、自定义函数 自定义函数使用function关键字。格式如下: function F_NAME([variable]) { statements } 格式: function name (parameter,parameter, ...) { statements return expression } 示例: function max(v1,v2) { v1>v2?var=v1:var=v2 return var } BEGIN{a=3;b=2;print max(a,b)} # awk –f fun.awk 函数还可以使用return语句返回值,格式为"return value" 19、给函数传递参数 注意:在BEGIN 过程 中不可用。直到 首行输入完成以后 ,变量才 可用 。可以通过-v 参数,让awk 在执行BEGIN 之前得到变量的值。命令行中每一个指定的变量都需要一个-v参数 示例: # cat test.awk #!/bin/awk –f {if($3>=min && $3<=max)print $1,$3} # chmod +x test.awk # test.awk -F: min=100 max=200 /etc/passwd 20、awk工作过程 1、执行BEGIN{action;… } 语句块中的语句 2、从文件或标准输入(stdin) 读取一行,然后执行pattern{action;… } 语句块,它逐行扫描文件,从第一行到最后一行重复这 个过程,直到文件全部被读取完毕。 3、当读至输入流末尾时,执行END{action;…} 语句块BEGIN 语句块在awk 开始从输入流中读取行之前被执行,这是一个可选的 语句块,比如变量初始化、打印输出表格的表头等语句通常可以写在BEGIN 语句块中END 语句块在awk 从输入流中读取完所 有的行之后即被执行,比如打印所有行的分析结果这类信息汇总都是在END 语句块中完成,它也是一个可选语句块pattern 语句块中的通用命令是最重要的部分,也是可选的。如果没有提供pattern 语句块,则默认执行{ print } ,即打印每一个读 取到的行,awk读取的每一行都会执行该语句块。 21、注意 1、在 awk 中也可以使用 bash 中定义的变量 2、printf 默认不输出换行符号 3、打印奇数行 seq 10 | awk 'i=!i' 打印偶数行 seq 10 | awk '!(i=!i)' 4、计算1~100的和 awk 'BEGIN{i=1;while(i<=100){sum+=i;i++};print sum}' 5、比较 awk 和 bash 计算的性能 time awk 'BEGIN{i=1;while(i<=100000){sum+=i;i++};print sum}' for ((sum=0,i=1;i<=100000;i++));do let sum+=i;done;echo $sum seq -s + 1 100000 | bc awk 的性能明显比 for 的性能好 6、只打印第一行 awk -v n=0 '!n++' /file/path/name 7、去除重复行 awk -F: '!line[$7]++' /etc/passwd line[$7] 的初始值为0,所以打印一次,当$7出现第二次时,line[$7]的值为非0的数,此时取反值为0,就不打印了。 能后达到取出重复行的目的。 22、awk 调用 shell 命令 system函数 功能:调用 shell 中的命令 示例: 空格是awk中的字符串连接符,如果system中需要使用awk中的变量可以使用空格分隔,或者说除了awk的变量外其他一律 用""引用起来。 awk 'BEGIN{system("hostname")}' awk 'BEGIN{score=100;system("echo your score is" score)}'