shell文本处理
shell文本处理
一、grep
过滤来自一个文件或标准输入匹配模式内容。除了 grep 外,还有 egrep、fgrep。egrep 是 grep 的扩展,相当于 grep -E。fgrep 相当于 grep -f,用的比较少。
-
用法
grep [OPTION]... PATTERN [FILE]...
支持的正则 描述 -E,–extended-regexp 模式是扩展正则表达式(ERE) -P,–perl-regexp 模式是 Perl 正则表达式 -e,–regexp=PATTERN 使用模式匹配,可指定多个模式匹配 -f,–file=FILE 从文件每一行获取匹配模式 -i,–ignore-case 忽略大小写 -w,–word-regexp 模式匹配整个单词 -x,–line-regexp 模式匹配整行 -v,–invert-match 打印不匹配的行 输出控制 描述 -m,–max-count=NUM 输出匹配的结果 num 数 -n,–line-number 打印行号 -H,–with-filename 打印每个匹配的文件名 -h,–no-filename 不输出文件名 -o,–only-matching 只打印匹配的内容 -q,–quiet 不输出正常信息 -s, --no-messages 不输出错误信息 -r,–recursive 递归目录 -c,–count 只打印每个文件匹配的行数 –include=FILE_PATTERN 只检索匹配的文件 –exclude=FILE_PATTERN 跳过匹配的文件 –exclude-from=FILE 跳过匹配的文件,来自文件模式 –exclude-dir=PATTERN 跳过匹配的目录 内容行控制 描述 -B,–before-context=NUM 打印匹配的前几行 -A,–after-context=NUM 打印匹配的后几行 -C,–context=NUM 打印匹配的前后几行 –color[=WHEN] 匹配的字体颜色 -
示例:
- 输出 b 文件中在 a 文件相同的行
# grep -f a b
- 输出 b 文件中在 a 文件不同的行
# grep -v -f a b
- 匹配多个模式
# echo "a bc de" |xargs -n1 |grep -e 'a' -e 'bc' a bc
- 去除空格 http.conf 文件空行或开头#号的行
# grep -E -v "^$|^#" /etc/httpd/conf/httpd.conf
匹配开头不分大小写的单词
# echo "A a b c" |xargs -n1 |grep -i a 或 # echo "A a b c" |xargs -n1 |grep '[Aa]' A a
- 只显示匹配的字符串
# echo "this is a test" |grep -o 'is' is is
- 输出匹配的前五个结果
# seq 1 20 |grep -m 5 -E '[0-9]{2}' 10 11 12 13 14
- 统计匹配多少行
# seq 1 20 |grep -c -E '[0-9]{2}' 11
- 匹配 b 字符开头的行
# echo "a bc de" |xargs -n1 |grep '^b'bc
- 匹配 de 字符结尾的行并输出匹配的行
# echo "a ab abc abcd abcde" |xargs -n1 |grep -n 'de$' 5:abcde
- 递归搜索/etc 目录下包含 ip 的 conf 后缀文件
# grep -r '192.167.1.1' /etc --include *.conf
- 排除搜索 bak 后缀的文件
# grep -r '192.167.1.1' /opt --exclude *.bak
- 排除来自 file 中的文件
# grep -r '192.167.1.1' /opt --exclude-from file
- 匹配 41 或 42 的数字
# seq 41 45 |grep -E '4[12]' 41 42
- 匹配至少 2 个字符
# seq 13 |grep -E '[0-9]{2}' 10 11 12 13
- 匹配至少 2 个字符的单词,最多 3 个字符的单词
# echo "a ab abc abcd abcde" |xargs -n1 |grep -E -w -o '[a-z]{2,3}' ab abc
- 匹配所有 IP
# ifconfig |grep -E -o "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}" # ifconfig |grep -E -o "[0-9]{1,3}\.{3}[0-9]{1,3}" # ifconfig | grep -E -o '((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
- 打印匹配结果及后 3 行
# seq 1 10 |grep 5 -A 3 5 6 7 8
- 打印匹配结果及前 3 行
# seq 1 10 |grep 5 -B 3 2 3 45
- 打印匹配结果及前后 3 行
# seq 1 10 |grep 5 -C 3 2 3 4 5 6 7 8
- 不显示输出
## 不显示错误输出: # grep 'a' abc grep: abc: No such file or directory # grep -s 'a' abc # echo $? 2 ## 不显示正常输出: # grep -q 'a' a.txt
二、sed
流编辑器,过滤和替换文本。
工作原理:sed 命令将当前处理的行读入模式空间进行处理,处理完把结果输出,并清空模式空间。然后再将下一行读入模式空间进行处理输出,以此类推,直到最后一行。还有一个空间叫保持空间,又称暂存空间,可以暂时存放一些处理的数据,但不能直接输出,只能放到模式空间输出。这两个空间其实就是在内存中初始化的一个内存区域,存放正在处理的数据和临时存放的数据。
-
用法
sed [OPTION]... {script-only-if-no-other-script} [input-file]... sed [选项] '地址 命令' file
选项 描述 -n 不打印模式空间 -e 执行脚本、表达式来处理 -f 执行动作从文件读取执行 -i 修改原文件 -r 使用扩展正则表达式 命令 描述 s/regexp/replacement/ 替换字符串 p 打印当前模式空间 P 打印模式空间的第一行 d 删除模式空间,开始下一个循环 D 删除模式空间的第一行,开始下一个循环 = 打印当前行号 a \text 当前行追加文本 i \text 当前行上面插入文本 c \text 所选行替换新文本 q 立即退出 sed 脚本 r 追加文本来自文件 : label label 为 b 和 t 命令 b label 分支到脚本中带有标签的位置,如果分支不存在则分支到脚本的末尾 t label 如果 s///是一个成功的替换,才跳转到标签 h H 复制/追加模式空间到保持空间 g G 复制/追加保持空间到模式空间 x 交换模式空间和保持空间内容 l 打印模式空间的行,并显示控制字符$ n N 读取/追加下一行输入到模式空间 w filename 写入当前模式空间到文件 ! 取反、否定 & 引用已匹配字符串 地址 描述 first~step 步长,每 step 行,从第 first 开始 $ 匹配最后一行 /regexp/ 正则表达式匹配行 number 只匹配指定行 addr1,addr2 开始匹配 addr1 行开始,直接 addr2 行结束 addr1,+N 从 addr1 行开始,向后的 N 行 addr1,~N 从 addr1 行开始,到 N 行结束 -
匹配打印:
-
借助以下文本内容作为示例讲解
# tail /etc/services aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
打印匹配axio开头的行
# tail /etc/services | sed -n '/^axio/p' axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol
-
打印第一行
# tail /etc/services | sed -n '1 p' aigairserver 21221/tcp # Services for Air Server
-
打印第一行至第三行
# tail /etc/services | sed -n '1,3 p' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery
-
打印奇数行
tail /etc/services | sed -n '1~2 p' aigairserver 21221/tcp # Services for Air Server ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery axio-disc 35100/tcp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System
-
打印匹配行及后一行
# tail /etc/services | sed -n '/pmw/,+1 p' pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive
-
打印最后一行
# tail /etc/services | sed -n '$ p' spremotetablet 46998/tcp # Capture handwritten signatures
-
不打印最会一行
# tail /etc/services | sed -n '$ !p' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System
-
匹配范围
# tail /etc/services | sed -n '/^axio/,/^pmw/ p' axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API
-
匹配开头行到最后一行
# tail /etc/services | sed -n '/^axio/,$ p' axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
引用系统变量,用引号
# tail /etc/services | sed -n "$a,3 p" aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery # tail /etc/services | sed -n ''$a',3 p' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery
-
注意:
- sed 命令用单引号时,里面变量用单引号引起来,或者 sed 命令用双引号,因为双引号解释特殊符号原有意义。
- 感叹号也就是对后面的命令取反。
-
-
匹配删除:
打印是把匹配的打印出来,删除是把匹配的删除,删除只是不用-n 选项。
# tail /etc/services | sed '/axio/ d' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures# tail /etc/services | sed '1 d' ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures# tail /etc/services | sed '1~2 d' ka-kdp 31016/udp # Kollective Agent Kollective Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/udp # Axiomatic discovery protocol cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive spremotetablet 46998/tcp # Capture handwritten signatures# tail /etc/services | sed '1,3 d' edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures## 去除空格http.conf文件空行或开头#号的行 # sed '/^#/d;/^$/d' /etc/httpd/conf/httpd.conf
-
替换 s/ / /
-
替换axio-disc字符串为test
# tail /etc/services | sed 's/axio-disc/test/' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service test 35100/tcp # Axiomatic discovery protocol test 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
替换开头是axio-disc的字符串并打印
# tail /etc/services | sed -n 's/^axio-disc/test/ p' test 35100/tcp # Axiomatic discovery protocol test 35100/udp # Axiomatic discovery protocol
-
使用&命令引用匹配内容并替换
# tail /etc/services | sed 's/21221/&.0/' aigairserver 21221.0/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
IP加引号
echo '172.25.254.100 172.25.254.101 172.25.254.102' | sed -r 's/[^ ]+/"&"/g' "172.25.254.100" "172.25.254.101" "172.25.254.102"
-
对1-4行的ka-kdp进行替换
# tail /etc/services | sed '1,4s/ka-kdp/test/' aigairserver 21221/tcp # Services for Air Server test 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
对匹配行进行替换
tail /etc/services | sed '/21221\/tcp/s/aigairserver/test/' test 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
二次匹配替换
# tail /etc/services | sed '/21221\/tcp/s/aigairserver/test/;s/ka-kdp/test/' test 21221/tcp # Services for Air Server test 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
分组使用,在每个字符串后面添加123
# tail /etc/services | sed -r 's/(.*) (.*)(#.*)/\1\2test \3/' aigairserver 21221/tcp test # Services for Air Server ka-kdp 31016/udp test # Kollective Agent Kollective Delivery ka-sddp 31016/tcp test # Kollective Agent Secure Distributed Delivery edi_service 34567/udp test # dhanalakshmi.org EDI Service axio-disc 35100/tcp test # Axiomatic discovery protocol axio-disc 35100/udp test # Axiomatic discovery protocol pmwebapi 44323/tcp test # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp test # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp test # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp test # Capture handwritten signatures
-
将协议与端口号位置调换
# tail /etc/services | sed -r 's/(.*)(\<[0-9]+\>)\/(tcp|udp)(.*)/\1\3\/\2\4/' aigairserver tcp/21221 # Services for Air Server ka-kdp udp/31016 # Kollective Agent Kollective Delivery ka-sddp tcp/31016 # Kollective Agent Secure Distributed Delivery edi_service udp/34567 # dhanalakshmi.org EDI Service axio-disc tcp/35100 # Axiomatic discovery protocol axio-disc udp/35100 # Axiomatic discovery protocol pmwebapi tcp/44323 # Performance Co-Pilot client HTTP API cloudcheck-ping udp/45514 # ASSIA CloudCheck WiFi Management keepalive cloudcheck tcp/45514 # ASSIA CloudCheck WiFi Management System spremotetablet tcp/46998 # Capture handwritten signatures
-
位置调换
## 替换x字符为大写 # echo "abc cde xyz" | sed -r 's/(.*)x/\1X/' abc cde Xyz ## 456与cde调换: # echo "abc:cde;123:456" | sed -r 's/([^:]+)(;.*:)([^:]+$)/\3\2\1/' abc:456;123:cde
-
注释匹配行后的多少行
# seq 10 | sed '/5/,+3s/^/#/' 1 2 3 4 #5 #6 #7 #8 9 10
-
注释指定多行
# seq 5 | sed -r '/^3|^4/s/^/#/' 1 2 #3 #4 5 # seq 5 | sed -r 's/^3|^4/#\0/' 1 2 #3 #4 5
-
去除开头和结尾空格或制表符
# echo " 1 2 3 "|sed 's/^[ \t]]*//;s/[ \t]*$//' 1 2 3
-
-
多重编辑(-e)
# tail /etc/services | sed -e '1,2d' -e 's/axio-disc/test/' ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service test 35100/tcp # Axiomatic discovery protocol test 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures## 也可以使用分号分隔 # tail /etc/services | sed '1,2d;s/axio-disc/test/' ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service test 35100/tcp # Axiomatic discovery protocol test 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
添加新内容(a、i和c)
-
在axio-disc上一行添加test
# tail /etc/services | sed '/axio-disc/i \test' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service test axio-disc 35100/tcp # Axiomatic discovery protocol test axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
在axio-disc下一行添加test
# tail /etc/services | sed '/axio-disc/a \test' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol test axio-disc 35100/udp # Axiomatic discovery protocol test pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
将axio-disc替换新行
# tail /etc/services | sed '/axio-disc/c \test' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service test test pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
在指定行下一行添加一行
# tail /etc/services | sed '2a \test' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery test ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
在指定行的前面和后面添加一行
# seq 5 | sed '3s/.*/txt\n&/' 1 2 txt 3 4 5# seq 5 | sed '3s/.*/&\ntxt/' 1 2 3 txt 4 5
-
-
读取文件并追加到匹配行后(r)
# cat a.txt 123 456# tail /etc/services | sed '/axio-disc/r a.txt' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol 123 456 axio-disc 35100/udp # Axiomatic discovery protocol 123 456 pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
将匹配行写入文件(w)
# tail /etc/services | sed '/axio-disc/w b.txt' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures # cat b.txt axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol
-
读取下一行(n和N)
-
n:读取下一行到模式空间。
-
N:追加下一行内容到模式空间,并以换行符\n分隔。
-
打印匹配的下一行
seq 5 | sed -n '/3/{n;p}' 4
-
打印偶数
# seq 6 | sed -n 'n;p' 2 4 6 ## sed 先读取第一行 1,执行 n 命令,获取下一行 2,此时模式空间是 2,执行 p 命令,打印模式空间。 现在模式空间是 2,sed 再读取 3,执行 n 命令,获取下一行 4,此时模式空间为 4,执行 p 命令,以此类推。
-
打印奇数
# seq 6 | sed 'n;d' 1 3 5 ## sed 先读取第一行 1,此时模式空间是 1,并打印模式空间 1,执行 n 命令,获取下一行 2,执行 d命令,删除模式空间的 2,sed 再读取 3,此时模式空间是 3,并打印模式空间,再执行 n 命令,获取下一行 4,执行 d 命令,删除模式空间的 3,以此类推。
-
每三行执行一次p命令
# seq 6 | sed 'n;n;p' 1 2 3 3 4 5 6 6 ## sed 先读取第一行 1,并打印模式空间 1,执行 n 命令,获取下一行 2,并打印模式空间 2,再执行 n命令,获取下一行 3,执行 p 命令,打印模式空间 3。sed 读取下一行 3,并打印模式空间 3,以此类推。
-
每三行替换一次
## 我们只是把 p 命令改成了替换命令。 # seq 6 | sed 'n;n;s/^/=/;s/$/=/' 1 2 =3= 4 5 =6= ## 这次用到了地址匹配,来实现上面的效果:当执行多个 sed 命令时,有时相互会产生影响,我们可以用大括号{}把他们括起来。 # seq 6 | sed '3~3{s/^/=/;s/$/=/}' 1 2 =3= 4 5 =6= ## 当执行多个 sed 命令时,有时相互会产生影响,我们可以用大括号{}把他们括起来
-
N:追加下一行内容到模式空间,并以换行符\n分隔。
## sed 读取第一行 1,N 命令读取下一行 2,并以\n2 追加,此时模式空间是 1\n2,再执 行 q 退出。 # seq 6 | sed 'N;q' 1 2## 执行 N 命令后,此时模式空间是 1\n2,再执行把\n 替换为空,此时模式空间是 12,并打印 # seq 6 | sed 'N;s/\n//' 12 34 56## N 命令是读取下一行追加到 sed 读取的当前行,当 N 读取下一行没有内容时,则退出,也不会执行 p 命令打印当前行,所以不会打印5。 # seq 5 | sed -n 'N;p' 1 2 3 4 # seq 6 | sed -n 'N;p' 1 2 3 4 5 6## 打印奇数行的最后一行,加一个满足条件,当 sed 执行到最后一行时,用感叹号不去执行 N 命令,随后执行 p 命令。 # seq 5 | sed -n '$!N;p' 1 2 3 4 5
-
-
打印和删除模式空间的第一行(P和D)
-
P:打印模式空间的第一行。
-
D:删除模式空间的第一行。
-
打印奇数
# seq 6 | sed -n 'N;P' 1 3 5
-
保留最后一行
# seq 6 | sed 'N;D' 6 ## 读取第一行 1,执行 N 命令读取下一行并追加到模式空间,此时模式空间是 1\n2,执行 D 命令删除模式空间第一行 1,剩余 2。 读取第二行,执行 N 命令,此时模式空间是 3\n4,执行 D 命令删除模式空间第一行 3,剩余 4。以此类推,读取最后一行打印时,而 N 获取不到下一行则退出,不再执行 D,因此模式空间只剩余 6就打印。
-
-
保持空间操作(h与H、g与G和x)
-
h:复制模式空间内容到保持空间(覆盖)。
-
H:复制模式空间内容追加到保持空间。
-
g:复制保持空间内容到模式空间(覆盖)。
-
G:复制保持空间内容追加到模式空间。
-
x:模式空间与保持空间内容互换。
-
将匹配的内容覆盖到另一个匹配
# seq 6 | sed -e '/3/{h;d}' -e '/5/g' 1 2 4 3 6 ## h 命令把匹配的 3 复制到保持空间,d 命令删除模式空间的 3。后面命令再对模式空间匹配 5,并用g 命令把保持空间 3 覆盖模式空间 5。
-
将匹配的内容放到最后
# seq 6 | sed -e '/3/{h;d}' -e '$G' 1 2 4 5 6 3
-
交换模式空间和保持空间
# seq 6 | sed -e '/3/{h;d}' -e '/5/x' -e '$G' 1 2 4 3 6 5
-
倒叙输出
# seq 5 | sed '1!G;h;$!d' 5 4 3 2 1 ## 1!G 第一行不执行把保持空间内容追加到模式空间,因为现在保持空间还没有数据。 h 将模式空间放到保持空间暂存。 $!d 最后一行不执行删除模式空间的内容。 读取第一行 1 时,跳过 G 命令,执行 h 命令将模式空间 1 复制到保持空间,执行 d 命令删除模式空间的 1。 读取第二行 2 时,模式空间是 2,执行 G 命令,将保持空间 1 追加到模式空间,此时模式空间是2\n1,执行 h 命令将 2\n1 覆盖到保持空间,d 删除模式空间。 读取第三行 3 时,模式空间是 3,执行 G 命令,将保持空间 2\n1 追加到模式空间,此时模式空间是3\n2\n1,执行 h 命令将模式空间内容复制到保持空间,d 删除模式空间。 以此类推,读到第 5 行时,模式空间是 5,执行 G 命令,将保持空间的 4\n3\n2\n1 追加模式空间,然后复制到模式空间,5\n4\n3\n2\n1,不执行 d,模式空间保留,输出。 由此可见,每次读取的行先放到模式空间,再复制到保持空间,d 命令删除模式空间内容,防止输出,再追加到模式空间,因为追加到模式空间,会追加到新读取的一行的后面,循环这样操作, 就把所有行一行行追加到新读取行的后面,就形成了倒叙。
-
每行后面添加新空行
# seq 5 | sed G 12345
-
打印匹配行的上一行
# seq 5 | sed -n '/3/{x;p};h' 2 ## 读取第一行 1,没有匹配到 3,不执行{x;p},执行 h 命令将模式空间内容 1 覆盖到保持空间。 读取第二行 2,没有匹配到 3,不执行{x;p},执行 h 命令将模式空间内容 2 覆盖到保持空间。 读取第三行 3,匹配到 3,执行 x 命令把模式空间 3 与保持空间 2 交换,再执行 p 打印模式空间 2.以此类推。
-
打印匹配行到最后一行或下一行到最后一行
## 打印匹配行到最后一行 # seq 5 |sed -n '/3/,$p' 3 4 5 # seq 5 |sed -n '/3/,${h;x;p}' 3 4 5 # seq 5 |sed -n '/3/{:a;N;$!ba;p}' 3 4 5 ## 打印匹配行的下一行到最后一行 # seq 5 |sed -n '/3/{n;:a;N;$!ba;p}' 4 5## 匹配到 3 时,n 读取下一行 4,此时模式空间是 4,执行 N 命令读取下一行并追加到模式空间,此时模式空间是 4\n5,标签循环完成后打印模式空间 4\n5。
-
-
标签(:、b和t)
-
标签可以控制流,实现分支判断。
-
:lable name 定义标签。
-
b lable 跳转到指定标签,如果没有标签则到脚本末尾。
-
t label 跳转到指定标签,前提是s///命令执行成功。
-
将换行符替换成逗号
## 方法1 # seq 6 | sed 'N;s/\n/,/' 1,2 3,4 5,6 ## 这种方式并不能满足我们的需求,每次 sed 读取到模式空间再打印是新行,替换\n 也只能对 N 命令追加后的 1\n2 这样替换。## 使用标签::a 是定义的标签名,b a 是跳转到 a 位置。 sed 读取第一行 1,N 命令读取下一行 2,此时模式空间是 1\n2$,执行替换,此时模式空间是1,2$,执行 b 命令再跳转到标签 a 位置继续执行 N 命令,读取下一行 3 追加到模式空间,此时模式空间是 1,2\n3$,再替换,以此类推,不断追加替换,直到最后一行 N 读不到下一行内容退出。 # seq 6 | sed ':a;N;s/\n/,/;b a' 1,2,3,4,5,6## 方法2:先将每行读入到模式空间,最后再执行全局替换。$!是如果是最后一行,则不执行 b a 跳转,最后执行全局替换。 # seq 6 | sed ':a;N;$!b a;s/\n/,/g' 1,2,3,4,5,6
-
每三个数字加一个逗号
# echo '123456789' | sed -r ':a ;s/([0-9]+)([0-9]+{3})/\1,\2/;t a' 123,456,789 ## 执行第一次时,替换最后一个,跳转后,再对 123456 匹配替换,直到匹配替换不成功,不执行 t 命令。
-
-
忽略大小写匹配(I)
# echo -e "a\nA\nb\nc" | sed 's/a/1/Ig' 1 1 b c
-
获取总行数($=)
# seq 10 |sed -n '$='
三、awk
awk 是一个处理文本的编程语言工具,能用简短的程序处理标准输入或文件、数据排序、计算以及生成报表等等。
在 Linux 系统下默认 awk 是 gawk,它是 awk 的 GNU 版本。可以通过命令查看应用的版本:ls -l /bin/awk
awk 处理的工作方式与数据库类似,支持对记录和字段处理,这也是 grep 和 sed 不能实现的。
在 awk 中,缺省的情况下将文本文件中的一行视为一个记录,逐行放到内存中处理,而将一行中的某一部分作为记录中的一个字段。用 1,2,3…数字的方式顺序的表示行(记录)中的不同字段。用$后跟数字,引用对应的字段,以逗号分隔,0 表示整个行。
-
基本语法命令
awk option 'pattern {action}' file 其中 pattern 表示 AWK 在数据中查找的内容,而 action 是在找到匹配内容时所执行的一系列命令。花括号用于根据特定的模式对一系列指令进行分组。
-
选项
选项 描述 -f program-file 从文件中读取 awk 程序脚本源文件 -F fs 指定 fs 为输入字段分隔符 -v var=value 变量赋值 –posix 兼容 POSIX 正则表达式 –dump-variables=[file] 把 awk 命令时的全局变量写入文件,默认文件是awkvars.out –profile=[file] 格式化 awk 语句到文件,默认是 awkprof.out -
模式
Pattern Description BEGIN{ } 给程序赋予初始状态,先执行的工作 END{ } 程序结束之后执行的一些扫尾工作 /regular expression/ 为每个输入记录匹配正则表达式 pattern && pattern 逻辑 and,满足两个模式 pattern || pattern 逻辑 or,满足其中一个模式 ! pattern 逻辑 not,不满足模式 pattern1, pattern2 范围模式,匹配所有模式 1 的记录,直到匹配到模式 2 -
动作:print、流程控制、I/O语句等
-
从文件读取awk程序处理文件
# vim test.awk {pringt $2} # tail -n3 /etc/services | awk -f test.awk 45514/udp 45514/tcp 46998/tcp
-
指定分隔符,打印指定字段
## 打印第二个字段,默认以空格分隔 # tail -n3 /etc/services | awk '{print $2}' 45514/udp 45514/tcp 46998/tcp ## 指定冒号为分隔符打印第一字段 # awk -F ':' '{print $1}' /etc/passwd root bin daemon adm lp sync ......
-
指定多个分隔符,作为同一个分隔符处理
# tail -n3 /etc/services | awk -F'[/#]' '{print $3}'ASSIA CloudCheck WiFi Management keepaliveASSIA CloudCheck WiFi Management SystemCapture handwritten signatures# tail -n3 /etc/services | awk -F'[ /]' '{print $1}' cloudcheck-ping cloudcheck spremotetablet# tail -n3 /etc/services | awk -F'/' '{print $1}' cloudcheck-ping 45514 cloudcheck 45514 spremotetablet 46998
-
变量赋值
# awk -v a=123 'BEGIN{print a}' 123 ## 系统变量作为awk变量的值 # a=123 # awk -v a=$a 'BEGIN{print a}' 123 ## 使用单引号 # awk 'BEGIN{print '$a'}' 123
-
输出awk全局变量到文件
# seq 5 | awk --dump-variables '{print $0}' 1 2 3 4 5 # cat awkvars.out ARGC: 1 ARGIND: 0 ARGV: array, 1 elements BINMODE: 0 CONVFMT: "%.6g" ENVIRON: array, 27 elements ERRNO: "" FIELDWIDTHS: "" FILENAME: "-" FNR: 5 FPAT: "[^[:space:]]+" FS: " " FUNCTAB: array, 41 elements IGNORECASE: 0 LINT: 0 NF: 1 NR: 5 OFMT: "%.6g" OFS: " " ORS: "\n" PREC: 53 PROCINFO: array, 21 elements RLENGTH: 0 ROUNDMODE: "N" RS: "\n" RSTART: 0 RT: "\n" SUBSEP: "\034" SYMTAB: array, 28 elements TEXTDOMAIN: "messages"
-
BEGIN 和 END
-
BEGIN:BEGIN 模式是在处理文件之前执行该操作,常用于修改内置变量、变量赋值和打印输出的页眉或标题。
## 打印页眉 # tail /etc/services | awk 'BEGIN{print "Service\t\tPort\t\t\tDescription\n=="}{print $0}' Service Port Description == aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
END:END 模式是在程序处理完才会执行。
## 打印页尾 # tail /etc/services | awk '{print $0}END{print "==\nEND......"}' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures == END......
-
-
格式化输出awk命令到文件
# tail /etc/services | awk --profile 'BEGIN{print "Service\t\tPort\t\t\tDescription\n==="}{print $0}END{print "===\nEND......"}' Service Port Description === aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures === END...... # cat awkprof.out# gawk profile, created Sun Feb 9 05:17:03 2025# BEGIN rule(s)BEGIN {1 print "Service\t\tPort\t\t\tDescription\n==="}# Rule(s)10 {10 print $0}# END rule(s)END {1 print "===\nEND......"}
-
/re/正则匹配
# tail /etc/services | awk '/tcp/{print $0}' aigairserver 21221/tcp # Services for Air Server ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery axio-disc 35100/tcp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
逻辑and、or和not
-
匹配记录中包含 axio 和 tcp 的行:
# tail /etc/services | awk '/axio/ && /tcp/{print $0}' axio-disc 35100/tcp # Axiomatic discovery protocol
-
匹配记录中包含axio 或 tcp 的行:
# tail /etc/services | awk '/axio/ || /tcp/{print $0}' aigairserver 21221/tcp # Services for Air Server ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
不匹配开头是#和空行:
# awk '! /^#/ && ! /^$/{print $0}' /etc/httpd/conf/httpd.conf # awk '/^[^#]/ && !/^$/' /etc/httpd/conf/httpd.conf # awk '/^[^#] | ^$/' /etc/httpd/conf/httpd.conf
-
-
匹配范围
# tail /etc/services | awk '/^axio/,/^cloudcheck/' axio-disc 35100/tcp # Axiomatic discovery protocol axio-disc 35100/udp # Axiomatic discovery protocol pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive## 对匹配范围后记录再次处理,例如匹配关键字下一行到最后一行: # seq 5 |awk '/3/,/^$/{printf /3/?"":$0"\n"}' 4 5# seq 5 | awk '/3/{t=1;next}t' 4 5 ## 1 和 2 都不匹配 3,不执行后面{},执行 t,t 变量还没赋值,为空,空在 awk 中就为假,就不打印当前行。匹配到 3,执行 t=1,next 跳出,不执行 t。4 也不匹配 3,执行 t,t 的值上次赋值的 1,为真,打印当前行,以此类推。(非 0 的数字都为真,所以 t 可以写任意非 0 数字)如果想打印匹配行都最后一行,就可以这样了: # seq 5 | awk '/3/{t=1}t' 3 4 5
-
-
内置变量
变量名 描述 FS
OFS输入字段分隔符,默认是空格或制表符
输出字段分隔符,默认是空格RS
ORS输入记录分隔符,默认是换行符\n
输出记录分隔符,默认是换行符\nNF
NR统计当前记录中字段个数
统计记录编号,每处理一行记录,编号就会+1FNR 统计记录编号,每处理一行记录,编号也会+1,与 NR 不同的是,处理第二个文件时,编号会重新计数。 ARGC 命令行参数数量 ARGV 命令行参数数组序列数组,下标从 0 开始,ARGV[0]是 awk ARGIND 当前正在处理的文件索引值。第一个文件是 1,第二个文件是 2,以此类推 EVNIRON 当前系统的环境变量 FILENAME 输出当前处理的文件名 IGNORECASE 忽略大小写 SUBSEP 数组中下标的分隔符,默认为"\034" -
示例:
-
FS和OFS
## 在程序开始前重新赋值 FS 变量,改变默认分隔符为冒号,与-F 一样。 # awk 'BEGIN{FS=":"}{print $1,$2}' /etc/passwd | head -5 root x bin x daemon x adm x lp x## 也可以使用-v来重新赋值这个变量 # awk -vFS=":" '{print $1,$2}' /etc/passwd | head -5 root x bin x daemon x adm x lp x##由于OFS默认是以空格分隔,反向引用多个字段分隔也是空格,如果想指定输出分隔符这样; # awk 'BEGIN{FS=":";OFS=":"}{print $1,$2}' /etc/passwd | head -n5 root:x bin:x daemon:x adm:x lp:x## 也可以通过字符串拼接实现分隔awk 'BEGIN{FS=":"}{print $1"#"$2}' /etc/passwd|head -5 root#x bin#x daemon#x adm#x lp#x
-
RS和ORS
## RS默认是\n分隔每行,如果想指定以某个字符作为分隔符来处理记录; # echo "www.baidu.com/user/test.html" | awk 'BEGIN{RS="/"}{print $0}' www.baidu.com user test.html## RS也支持正则,简单演示 # seq -f "str%02g" 10 | sed 'n;n;a\---'| awk 'BEGIN{RS="-+"}{print $1}' str01 str04 str07 str10## 将输出的换行符替换为+号; # seq 10 | awk 'BEGIN{ORS="+"}{print $0}' 1+2+3+4+5+6+7+8+9+10+##替换某个字符 # tail -n2 /etc/services | awk 'BEGIN{RS="/";ORS="#"}{print $0}' cloudcheck 45514#tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998#tcp # Capture handwritten signatures
-
NF:NF是字段个数
# echo "a b c d e f"|awk '{print NF}' 6## 打印最后一个字段: # echo "a b c d e f"|awk '{print $NF}' f## 打印倒数第二个字段: # echo "a b c d e f"|awk '{print $(NF-1)}' e## 排除最后两个字段: # echo "a b c d e f"|awk '{$NF="";$(NF-1)="";print $0}' a b c d## 排除第一个字段: # echo "a b c d e f"|awk '{$1="";print $0}'b c d e f
-
NR和FNR
NR 统计记录编号,每处理一行记录,编号就会+1,FNR 不同的是在统计第二个文件时会重新计数。
## 打印行数 # tail -n5 /etc/services|awk '{print NR,$0}' 1 axio-disc 35100/udp # Axiomatic discovery protocol 2 pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API 3 cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive 4 cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System 5 spremotetablet 46998/tcp # Capture handwritten signatures## 打印总行数 # tail -n5 /etc/services|awk 'END{print NR}' 5 ## 打印第三行 # tail -n5 /etc/services|awk 'NR==3' cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive ## 打印第三行的第二个字段 # tail -n5 /etc/services|awk 'NR==3{print $2}' 45514/udp ## 打印前三行 # tail -n5 /etc/services|awk 'NR<=3{print NR,$0}' 1 axio-disc 35100/udp # Axiomatic discovery protocol 2 pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API 3 cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive
接下来,我们来看看NR和FNR的区别
[root@openEulter-1 ~]# cat a.txt a b c [root@openEulter-1 ~]# cat b.txt c d e [root@openEulter-1 ~]# awk '{print NR,FNR,$0}' a.txt b.txt 1 1 a 2 2 b 3 3 c 4 1 c 5 2 d 6 3 e ## 我们可以发现:NR 每处理一行就会+1,而 FNR 在处理第二个文件时,编号重新计数。同时也知道 awk 处理两个文件时,是合并到一起处理。 [root@openEulter-1 ~]# awk 'FNR==NR{print $0"1"}FNR!=NR{print $0"2"}' a.txt b.txt a1 b1 c1 c2 d2 e2 ## 当 FNR==NR 时,说明在处理第一个文件内容,不等于时说明在处理第二个文件内容。
-
ARGC和ARGV
ARGC:是命令行参数数量;
ARGV:是将命令行参数存到数组,元素由ARGC指定,数组下标从0开始
[root@openEulter-1 ~]# awk 'BEGIN{print ARGC}' 1 2 3 4 [root@openEulter-1 ~]# awk 'BEGIN{print ARGV[0]}' awk [root@openEulter-1 ~]# awk 'BEGIN{print ARGV[1]}' 1 2 1 [root@openEulter-1 ~]# awk 'BEGIN{print ARGV[2]}' 1 2 2
-
ARGIND
ARGIND是当前正在处理的文件索引值,第一个文件是1,第二个文件是2,以此类推,从而可以通过这种方式判断正在处理哪个文件。
[root@openEulter-1 ~]# awk '{print ARGIND,$0}' a.txt b.txt 1 a 1 b 1 c 2 c 2 d 2 e [root@openEulter-1 ~]# awk 'ARGIND==1{print "a->"$0}ARGIND==2{print "b->"$0}' a.txt b.txt a->a a->b a->c b->c b->d b->e
-
ENVIRON
ENVIRON调用系统变量
[root@openEulter-1 ~]# awk 'BEGIN{print ENVIRON["HOME"]}' /root ## 如果是设置的环境变量,还需要用export导入到系统变量中才能调用 [root@openEulter-1 ~]# awk 'BEGIN{print ENVIRON["a"]}'[root@openEulter-1 ~]# export a=123 [root@openEulter-1 ~]# awk 'BEGIN{print ENVIRON["a"]}' 123
-
FILENAME
FILENAME是当前处理文件的文件名
[root@openEulter-1 ~]# awk 'FNR==NR{print FILENAME"->"$0}FNR!=NR{print FILENAME"->"$0}' a.txt b.txt a.txt->a a.txt->b a.txt->c b.txt->c b.txt->d b.txt->e
-
IGNORECASE
IGNORECASE=1代表忽略大小写
[root@openEulter-1 ~]# echo "A a b c"|xargs -n1|awk 'BEGIN{IGNORECASE=1}/a/' A a
-
-
操作符
运算符 描述 (…) 分组 $ 字段引用 ++ – 递增和递减 + - ! 加号:将字符串转化为数字,如果字符串以数字开头,则提取数字部分并输出,否则输出0
减号:将字符串转化为数字,如果字符串以数字开头,则提取数字部分并取反输出,否则输出0
逻辑否定| |& 乘、除、取余 < > <= >= != == 关系运算符 ~ !~ 正则表达式匹配,否定正则表达式匹配 in 数组成员 && || 逻辑and、逻辑or ?: 简写条件表达式:expr1 ? expr2 : expr3
第一个表达式为真,执行 expr2,否则执行 expr3= += -= *= /= %= ^= 变量赋值运算符 注意:
在 awk 中,有 3 种情况表达式为假:数字是 0,空字符串和未定义的值。
数值运算,未定义变量初始值为 0。字符运算,未定义变量初始值为空。
[root@openEulter-1 ~]# awk 'BEGIN{s="";if(s)print "true";else print"false"}' false [root@openEulter-1 ~]# awk 'BEGIN{n=0;if(n)print "true";else print "false"}' false [root@openEulter-1 ~]# awk 'BEGIN{if(n)print "true";else print "false"}' false
-
示例:
-
截取整数
[root@openEulter-1 ~]# echo "123abc abc123 123abc123"|xargs -n1 | awk '{print +$0}' 123 0 123 [root@openEulter-1 ~]# echo "123abc abc123 123abc123"|xargs -n1 | awk '{print -$0}' -123 0 -123
-
感叹号
# 打印奇数行 [root@openEulter-1 ~]# seq 6| awk 'i=!i' 1 3 5## 解释:当处理第一行输入时,执行 i=!i。此时 i 初始值为 0(false),!i 则为 1(true),并将 1 赋值给 i。由于 i 的值为 1(true),在 awk 中,条件为真时会默认执行 print 操作,所以会输出当前行,即 1。 当处理第二行输入时,再次执行 i=!i。此时 i 的值为 1(true),!i 为 0(false),并将 0 赋值给 i。因为 i 的值为 0(false),所以不会输出当前行。 当处理第三行输入时,又执行 i=!i。此时 i 的值为 0(false),!i 为 1(true),并将 1 赋值给 i。由于 i 的值为 1(true),所以会输出当前行,即 3。 以此类推,对于后续的每一行输入,i 的值会在 0 和 1 之间交替变化,导致奇数行对应的 i 值为 1(true)而被输出,偶数行对应的 i 值为 0(false)而不被输出# 打印偶数行 [root@openEulter-1 ~]# seq 6| awk '!(i=!i)' 2 4 6
-
不匹配某行
[root@openEulter-1 ~]# tail /etc/services | awk '!/axio/{print $0}' aigairserver 21221/tcp # Services for Air Server ka-kdp 31016/udp # Kollective Agent Kollective Delivery ka-sddp 31016/tcp # Kollective Agent Secure Distributed Delivery edi_service 34567/udp # dhanalakshmi.org EDI Service pmwebapi 44323/tcp # Performance Co-Pilot client HTTP API cloudcheck-ping 45514/udp # ASSIA CloudCheck WiFi Management keepalive cloudcheck 45514/tcp # ASSIA CloudCheck WiFi Management System spremotetablet 46998/tcp # Capture handwritten signatures
-
乘法和除法及取模
[root@openEulter-1 ~]# seq 5 | awk '{print $0*2}' 2 4 6 8 10 [root@openEulter-1 ~]# seq 5 | awk '{print $0/2}' 0.5 1 1.5 2 2.5 [root@openEulter-1 ~]# seq 5 | awk '$0%2==0{print $0}' 2 4 [root@openEulter-1 ~]# seq 5 | awk '$0%2!=0{print $0}' 1 3 5
-
管道符的使用
[root@openEulter-1 ~]# seq 5 | shuf | awk '{print $0|"sort"}' 1 2 3 4 5 ## shuf 命令用于对输入的行进行随机排序 ## print $0|"sort":这是一个管道操作。print $0 会将当前行的内容输出,| 是管道符号,它将 print 的输出传递给 sort 命令。sort 命令用于对输入的行进行排序,默认是按字典序升序排列。
-
正则表达式匹配
[root@openEulter-1 ~]# seq 5 | awk '$0~3{print $0}' 3 [root@openEulter-1 ~]# seq 5 | awk '$0!~3{print $0}' 1 2 4 5 [root@openEulter-1 ~]# seq 5 | awk '$0~/[34]/{print $0}' 3 4 [root@openEulter-1 ~]# seq 5 | awk '$0!~/[34]/{print $0}' 1 2 5 [root@openEulter-1 ~]# seq 5 | awk '$0~/[^34]/{print $0}' 1 2 5
-
判断数组成员
[root@openEulter-1 ~]# awk 'BEGIN{a["a"]=123}END{if("a" in a)print"yes"}'</dev/null yes
-
三目运算符
[root@openEulter-1 ~]# awk 'BEGIN{print 1==1?"yes":"no"}' yes [root@openEulter-1 ~]# seq 5 | awk '{print n=(n?n","$0:$0)}' 1 1,2 1,2,3 1,2,3,4 1,2,3,4,5 ## 解释:n?n","$0:$0:这是一个三元运算符表达式,其语法为 条件?表达式1:表达式2。如果条件为真,则返回表达式 1 的值;如果条件为假,则返回表达式 2 的值。 当处理第一行输入时,n 初始值为空字符串,在布尔语境下相当于 false。所以 n?n","$0:$0 会返回 $0,即当前行的内容。此时 n 被赋值为当前行内容 1,并通过 print 输出 1。 当处理第二行输入时,n 已经被赋值为 1,在布尔语境下为 true。所以 n?n","$0:$0 会返回 n","$0,也就是将 n 的值(即 1)和当前行内容 2 用逗号连接起来,得到 1,2。然后将 1,2 赋值给 n 并输出。 当处理第三行输入时,n 的值为 1,2,为 true。n?n","$0:$0 返回 n(即 1,2)和当前行内容 3 用逗号连接的结果 1,2,3,再将其赋值给 n 并输出。 以此类推,对于后续的每一行输入,都会将之前积累的内容 n 和当前行内容用逗号连接起来,更新 n 的值并输出。# 每三行后面添加新一行 [root@openEulter-1 ~]# seq 10 | awk '{print NR%3?$0:$0"\ntxt"}' 1 2 3 txt 4 5 6 txt 7 8 9 txt 10 # 两行合并一行 [root@openEulter-1 ~]# seq 6|awk '{printf NR%2!=0?$0" ":$0" \n"}' 1 2 3 4 5 6 [root@openEulter-1 ~]# seq 6|awk 'ORS=NR%2?" ":"\n"' 1 2 3 4 5 6 ## 解释: ORS:ORS 是 awk 的内置变量,代表输出记录分隔符(Output Record Separator),默认值是换行符 \n。awk 在输出每一行内容后,会自动添加 ORS 所代表的分隔符。 NR:NR 也是 awk 的内置变量,它表示当前处理的行号,从 1 开始计数。 NR%2:使用取模运算符 % 计算当前行号除以 2 的余数。如果余数为 1,说明当前行号是奇数;如果余数为 0,说明当前行号是偶数。 NR%2?" ":"\n":这是一个三元运算符表达式,语法为 条件?表达式1:表达式2。如果 NR%2 的结果为真(即余数为 1,当前行号是奇数),则返回表达式 1 的值,即空格 " ";如果 NR%2 的结果为假(即余数为 0,当前行号是偶数),则返回表达式 2 的值,即换行符 "\n"。 ORS=NR%2?" ":"\n":将三元运算符的结果赋值给 ORS。这意味着,当处理奇数行时,ORS 被设置为空格 " ";当处理偶数行时,ORS 被设置为换行符 "\n" [root@openEulter-1 ~]# seq 6 | awk '{if(NR%2)ORS=" ";else ORS="\n";print}' 1 2 3 4 5 6
-
变量赋值
# 字段求和 ## sum未初始化,默认值为0 [root@openEulter-1 ~]# seq 5 | awk '{sum+=1}END{print sum}' 5 [root@openEulter-1 ~]# seq 5 | awk '{sum+=$0}END{print sum}' 15
[root@openEulter-1 ~]# awk ‘BEGIN{print 1==1?“yes”:“no”}’
yes
[root@openEulter-1 ~]# seq 5 | awk ‘{print n=(n?n","$0:$0)}’
1
1,2
1,2,3
1,2,3,4
1,2,3,4,5解释:n?n","$0:$0:这是一个三元运算符表达式,其语法为 条件?表达式1:表达式2。如果条件为真,则返回表达式 1 的值;如果条件为假,则返回表达式 2 的值。
当处理第一行输入时,n 初始值为空字符串,在布尔语境下相当于 false。所以 n?n",“$0:$0 会返回 $0,即当前行的内容。此时 n 被赋值为当前行内容 1,并通过 print 输出 1。
当处理第二行输入时,n 已经被赋值为 1,在布尔语境下为 true。所以 n?n”,“$0:$0 会返回 n”,“$0,也就是将 n 的值(即 1)和当前行内容 2 用逗号连接起来,得到 1,2。然后将 1,2 赋值给 n 并输出。
当处理第三行输入时,n 的值为 1,2,为 true。n?n”,"$0:$0 返回 n(即 1,2)和当前行内容 3 用逗号连接的结果 1,2,3,再将其赋值给 n 并输出。
以此类推,对于后续的每一行输入,都会将之前积累的内容 n 和当前行内容用逗号连接起来,更新 n 的值并输出。每三行后面添加新一行
[root@openEulter-1 ~]# seq 10 | awk ‘{print NR%3?$0:$0"\ntxt"}’
1
2
3
txt
4
5
6
txt
7
8
9
txt
10两行合并一行
[root@openEulter-1 ~]# seq 6|awk ‘{printf NR%2!=0?$0" “:$0” \n"}’
1 2
3 4
5 6
[root@openEulter-1 ~]# seq 6|awk ‘ORS=NR%2?" “:”\n"’
1 2
3 4
5 6解释:
ORS:ORS 是 awk 的内置变量,代表输出记录分隔符(Output Record Separator),默认值是换行符 \n。awk 在输出每一行内容后,会自动添加 ORS 所代表的分隔符。
NR:NR 也是 awk 的内置变量,它表示当前处理的行号,从 1 开始计数。
NR%2:使用取模运算符 % 计算当前行号除以 2 的余数。如果余数为 1,说明当前行号是奇数;如果余数为 0,说明当前行号是偶数。
NR%2?" “:”\n":这是一个三元运算符表达式,语法为 条件?表达式1:表达式2。如果 NR%2 的结果为真(即余数为 1,当前行号是奇数),则返回表达式 1 的值,即空格 " “;如果 NR%2 的结果为假(即余数为 0,当前行号是偶数),则返回表达式 2 的值,即换行符 “\n”。
ORS=NR%2?” “:”\n":将三元运算符的结果赋值给 ORS。这意味着,当处理奇数行时,ORS 被设置为空格 " “;当处理偶数行时,ORS 被设置为换行符 “\n”
[root@openEulter-1 ~]# seq 6 | awk '{if(NR%2)ORS=” “;else ORS=”\n";print}’
1 2
3 4
5 6 -
变量赋值
# 字段求和 ## sum未初始化,默认值为0 [root@openEulter-1 ~]# seq 5 | awk '{sum+=1}END{print sum}' 5 [root@openEulter-1 ~]# seq 5 | awk '{sum+=$0}END{print sum}' 15
-
相关文章:

shell文本处理
shell文本处理 一、grep 过滤来自一个文件或标准输入匹配模式内容。除了 grep 外,还有 egrep、fgrep。egrep 是 grep 的扩展,相当于 grep -E。fgrep 相当于 grep -f,用的比较少。 用法 grep [OPTION]... PATTERN [FILE]...支持的正则描述…...

如何利用客户端双向TLS认证保护云上应用安全
双向TLS(mTLS)通过要求服务器和客户端双方使用数字证书来验证彼此身份,从而扩展了传统TLS的安全性。常规的TLS只会验证服务器的身份(如大家的浏览器在验证网站时的场景),而mTLS确保在任何数据交换发生之前,双方都对彼此持有信任。在本文中&am…...

nlp第十节——LLM相关
一、模型蒸馏技术 本质上是从一个大模型蒸馏出小模型,从小模型训练出来的概率分布(如自回归模型预测下一个字的概率分布)分别与大模型预测的概率分布和ground label求loss。与大模型预测的概率分布用KL散度求loss,与ground label用…...
T-SQL 语言基础: SQL 数据库对象元数据及配置信息获取
目录 介绍目录视图 获取表和架构名称获取列信息 信息架构视图 获取表信息获取列信息 系统存储过程和函数 获取对象列表获取对象详细信息获取约束信息获取数据库属性信息 总结引用 介绍 在 SQL 数据库管理中,获取数据库对象的元数据信息是至关重要的。元数据提供了…...

ue5 创建多列StreeView的方法与理解
创建StreeView的多列样式怎么就像是创建单行单列差不多?貌似就是在单行单列中加入了多列widget? 示例代码 DetailTabWidget #pragma once #include "TreeViewItemBase.h"class SDetailTabWidget : public SCompoundWidget {SLATE_BEGIN_ARGS(SDetailT…...

C# OnnxRuntime部署DAMO-YOLO香烟检测
目录 说明 效果 模型信息 项目 代码 下载 参考 说明 效果 模型信息 Model Properties ------------------------- --------------------------------------------------------------- Inputs ------------------------- name:input tensor:Floa…...

陕西省地标-DB61/T 1121-2018 政务服务中心建设和运营规范
揭秘陕西省智慧政务服务中心新标准:打造高效便捷的服务新体验 随着信息化时代的深入发展,智慧政务已成为提升政府服务效率、优化营商环境的重要举措。陕西省作为全国政务改革的先行者,近期颁布了《陕西省地标-DB61_T 1121-2018 政务服务中心…...

UDP协议(20250303)
1. UDP UDP:用户数据报协议(User Datagram Protocol),传输层协议之一(UDP,TCP) 2. 特性 发送数据时不需要建立链接,节省资源开销不安全不可靠的协议 //一般用在实时性比较高…...

【四.RAG技术与应用】【12.阿里云百炼应用(下):RAG的云端优化与扩展】
在上一篇文章中,我们聊了如何通过阿里云百炼平台快速搭建一个RAG(检索增强生成)应用,实现文档智能问答、知识库管理等基础能力。今天咱们继续深入,聚焦两个核心问题:如何通过云端技术优化RAG的效果,以及如何扩展RAG的应用边界。文章会穿插实战案例,手把手带你踩坑避雷。…...
Docker新手入门(持续更新中)
一、定义 快速构建、运行、管理应用的工具。 Docker可以帮助我们下载应用镜像,创建并运行镜像的容器,从而快速部署应用。 所谓镜像,就是将应用所需的函数库、依赖、配置等应用一起打包得到的。 所谓容器,为每个镜像的应用进程创建…...

【星云 Orbit • STM32F4】08. 用判断数据头来接收据的串口通用程序框架
【星云 Orbit • STM32F4】08. 用判断数据头来接收据的串口通用程序框架 1. 引言 本教程旨在帮助嵌入式开发小白从零开始,学习如何在STM32F407微控制器上实现一个基于串口的数据接收程序。该程序能够通过判断数据头来接收一串数据,并将其存储到缓冲区中…...
HSPF 水文模型建模方法与案例分析实践技术应用
在水文模拟领域,HSPF 模型(Hydrological Simulation Program Fortran)与 SWAT 模型一样,都是备受瞩目的水文模型软件。HSPF 模型因其强大的功能和简便的操作,在全球范围内得到了广泛应用。该模型不仅能够在缺乏测量数据…...

设置 CursorRules 规则
为什么要设置CursorRules? 设置 CursorRules 可以帮助优化代码生成和开发流程,提升工作效率。具体的好处包括: 1、自动化代码生成 :通过定义规则,Cursor 可以根据你的开发需求自动生成符合规定的代码模板,…...

人工智能AI在汽车设计领域的应用探索
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活…...

《当AI生成内容遭遇审核:需求与困境的深度剖析》:此文为AI自动生成
AI 内容审核:数字时代的守门人 在当今数字技术迅猛发展的浪潮中,AI 在内容生成领域取得了令人瞩目的成就,成为了推动创新与变革的核心力量。以 AI 绘画为例,从早期简单粗糙的图像生成,到如今能够创作出细节丰富、风格多…...

【无人机与无人车协同避障】
无人机与无人车协同避障的关键在于点云数据的采集、传输、解析及实时应用,以下是技术实现的分步解析: 1. 点云数据采集(无人机端) 传感器选择: LiDAR:通过激光雷达获取高精度3D点云(精度达厘米…...
ComfyUI AnimeDiff动画参数总结
ComfyUI AnimeDiff动画参数总结 一、动画生成核心参数 参数名称建议值/范围作用说明备注步数(Steps)15-25控制AI计算迭代次数,越高细节越精细,但耗时更长推荐20步,显存不足可降至15步CFG值7.0-8.5提示词对画面的控制…...

No manual entry for printf in section 3
问题描述 在尝试查看 printf 的 C 函数手册页(即 man 3 printf)时遇到了 “No manual entry for printf in section 3” 的错误信息。 解决方案 出现这问题,是由于系统上没有安装对应的部分的手册页,因此安装对应的部分的手册…...
React 之 Redux 第二十八节 学习目标与规划大纲及概要讲述
接下来 开始Redux 全面详细的文档输出,主要基于一下几个方面,欢迎大家补充指正 一、Redux 基础概念 为什么需要 Redux? 前端状态管理的挑战(组件间通信、状态共享) Redux 解决的问题:集中式、可预测的状态…...

OSPF路由ISIS路由与路由学习对比(OSPF vs ISIS Routing Learning Comparison)
OSPF路由ISIS路由与路由学习对比 1.OSPF 路由学习规律 OSPF使用链路状态数据库(Link State Database)来存储网络拓扑信息。每个OSPF路由器通过交换链路状态更新(Link State Updates)来了解整个网络的拓扑,并根据收到…...
基于大模型的 UI 自动化系统
基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...

(二)原型模式
原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

【LeetCode】算法详解#6 ---除自身以外数组的乘积
1.题目介绍 给定一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O…...

【深度学习新浪潮】什么是credit assignment problem?
Credit Assignment Problem(信用分配问题) 是机器学习,尤其是强化学习(RL)中的核心挑战之一,指的是如何将最终的奖励或惩罚准确地分配给导致该结果的各个中间动作或决策。在序列决策任务中,智能体执行一系列动作后获得一个最终奖励,但每个动作对最终结果的贡献程度往往…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
ArcPy扩展模块的使用(3)
管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如,可以更新、修复或替换图层数据源,修改图层的符号系统,甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...