日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

awk 内嵌正则 提取字符串_干货-Shell编程文本处理三剑客之-awk

發布時間:2025/3/19 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 awk 内嵌正则 提取字符串_干货-Shell编程文本处理三剑客之-awk 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

awk

在 Linux/UNIX 系統中,awk 是一個功能強大的編輯工具,逐行讀取輸入文本,并根據指定的匹配模式進行查找,對符合條件的內容進行格式化輸出或者過濾處理,可以在無交互的情況下實現相當復雜的文本操作,被廣泛應用于 Shell 腳本,完成各種自動化配置任務。

AWK是一種處理文本文件的語言,是一個強大的文本分析工具。之所以叫 AWK 是因為其取了三位創始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。

語法格式:

語法格式解釋:

語法格式含義
BEGIN{}正式處理數據之前執行
pattern匹配模式
{commands}處理命令,可能多行
END{}處理完所有匹配數據后執行

awk內置變量

內置變量含義
$0整行內容
$1~$n當前行的第1-n個字段
NF當前行的字段個數,也就是有多少列
NR當前行的行號,從1開始計數
FNR多文件處理時,每個文件行號單獨計數都是從0開始
FS輸入字段分隔符,不指定則默認以空格或tab鍵分隔
RS輸入行分隔符,默認回車換行
OFS輸出字段分隔符,默認為空格
ORS輸出行分隔符,默認回車換行
FILENAME當前輸入的文件名字
ARGC命令行參數個數
ARGV命令行參數數組

示例

以下所有示例文件為/etc/passwd,請將其拷貝一份使用

# 打印整行內容 awk '{print $0}' passwd# 使用":"號作為分隔符,輸出第一個字段 awk 'BEGIN{FS=":"}{print $1}' passwd ->root ->bin ->daemon ->adm ->lp ->sync ->shutdown ->...# 輸出行號 awk '{print NR}' passwd# 多個文件行號單獨計數 awk '{print FNR}' passwd file2# 指定行分隔符 echo "hello-world-hello-linux-hello-java" | awk 'BEGIN{RS="-"}{print $0}' ->hello ->world ->hello ->linux ->hello ->java -># 指定輸出字段分隔符 awk 'BEGIN{FS=":";OFS=":"}{print NR,$1}' passwd ->1:root ->2:bin ->3:daemon ->4:adm ->5:lp ->...

printf格式化輸出

格式符含義
%s打印字符串
%d打印十進制數
%f打印一個浮點數
%x打印十六進制數
%o打印八進制數
%e打印數字的科學計數法形式
%c打印單個字符的ASCII碼
-左對齊
+右對齊
#顯示8進制在前面加0,顯示16進制在前面加0x

示例

# 以字符串格式打印第1個字段,以":"作為分隔符 awk 'BEGIN{FS=":"}{printf "%st",$1}' passwd ->root bin daemon adm lp ...# 以字符串格式打印第1個字段和對應行號,輸出格式為"行號:字段內容" awk 'BEGIN{FS=":"}{printf "%d:%sn",NR,$1}' passwd ->1:root ->2:bin ->3:daemon ->4:adm ->5:lp ->...# 左對齊 # 在不指定位數的情況下默認左對齊,指定位數后為右對齊(必須指定位數) awk 'BEGIN{FS=":"}{printf "%10d:%sn",NR,$1}' passwd -> 1:root -> 2:bin -> 3:daemon -> 4:adm -> 5:lp ->...awk 'BEGIN{FS=":"}{printf "%-10d:%sn",NR,$1}' passwd ->1 :root ->2 :bin ->3 :daemon ->4 :adm ->5 :lp ->...

兩種匹配模式

模式含義
正則按正則表達式匹配
關系運算按關系運算匹配

關系運算符:

  • < : 小于
  • > : 大于
  • <= : 小于等于
  • >= : 大于等于
  • == : 等于
  • != : 不等于
  • ~ : 匹配正則表達式
  • !~ : 不匹配正則表達式

布爾運算符:

  • || : 或
  • && : 與
  • ! : 非
# 匹配文件行中含有root字符串的所有行 awk 'BEGIN{FS=":"}/root/{print $0}' passwd ->root:x:0:0:root:/root:/bin/bash ->operator:x:11:0:operator:/root:/sbin/nologin# 匹配第3個字段小于50的所有行信息 awk 'BEGIN{FS=":"}$3<50{print $0}' passwd# 匹配文件中包含mail或ftp的所有行信息 awk 'BEGIN{FS=":"}/mail/||/ftp/{print $0}' passwd ->mail:x:8:12:mail:/var/spool/mail:/sbin/nologin ->ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin# 匹配文件中第3個字段小于50并且第4個字段大于50的所有行信息 awk 'BEGIN{FS=":"}$3<50 && $4 > 50{print $0}' passwd ->games:x:12:100:games:/usr/games:/sbin/nologin# 匹配文件中第3個字段小于50并且第7個字段匹配/bin/bash的所有行信息 awk 'BEGIN{FS=":"}$3<50 && $7 ~ //bin/bash/{print $0}' passwd ->root:x:0:0:root:/root:/bin/bash

awk表達式

# 統計空白行數目 awk '/^$/{sum++}END{print sum}' /etc/services ->17# 統計一下學生成績總分和平均分,報表形式展示 姓名 語文 數學 英語 物理 張三 80 60 85 90 李四 85 65 80 75 王五 70 60 85 90 李華 65 80 84 91 王八 90 90 95 90awk 'BEGIN{printf "%-8s%-5s%-5s%-5s%-5s%-5s%-8sn","姓名","語文","數學","英語","物理","總分","平均分"}{total=$2+$3+$4+$5;avg=total/4;printf "%-8s%-8d%-6d%-8d%-7d%-5d%0.2fn",$1,$2,$3,$4,$5,total,avg}' stu.txt姓名 語文 數學 英語 物理 總分 平均分 張三 80 60 85 90 315 78.75 李四 85 65 80 75 305 76.25 王五 70 60 85 90 305 76.25 李華 65 80 84 91 320 80.00 王八 90 90 95 90 365 91.25

條件語句和循環語句

# 條件語句 if (條件表達式1){action1 }else if (條件表達式2){action2 }else{action3 }# 以":"為分隔符,如果第3個字段小于50,打印小于50,如果等于50則打印等于50,否則打印大于50 awk 'BEGIN{FS=":"}{if($3<50){print "小于50" }else if($3==50){ print "等于50"}else{print "大于50"}}' passwd# 我們可以將命令保存在一個文件(eg:oper.awk,后綴不硬性要求哦!)中使用-f選項引入 awk -f oper.awk passwd# 循環語句 while while(條件表達式){action }# 循環語句 do while do{action }while(條件表達式)# 循環語句 for for(初始化計數器;測試計數器;變更計數器){action }# 計算1+2+3+...+100的和。 awk 'BEGIN{do{i++;sum+=i;}while(i<100)print sum}' awk 'BEGIN{while(i<100){i++;sum+=i;}print sum}' awk 'BEGIN{for(i=0;i<=100;i++){sum+=i;}print sum}'

字符串函數

函數名含義函數返回值
length(str)計算字符串長度整數長度值
index(str1,str2)在str1中查找str2的位置位置索引,從1計數
tolower(str)轉換為小寫轉換后的小寫字符串
toupper(str)轉換為大寫轉換后的大寫字符串
substr(str,m,n)從str的m個字符開始,截取n位截取后的子串
split(str,arr,fs)按fs切割字符串,結果保存在arr中切割后的子串個數
match(str,RE)在str中按照RE查找,返回位置返回索引位置
sub(RE,RepStr,str)在str中搜索符合RE的子串,將其替換為RepStr,只替換第一個替換的個數
gsub(RE,RepStr,str)在str中搜索符合RE的子串,將其替換為RepStr,替換所有替換的個數

示例

# 以:為分隔符,返回文件每行中每個字段的長度 awk 'BEGIN{FS=":"}{for(i=1;i<=NF;i++){if(i==NF){printf "%d",length($i)}else{printf "%d:",length($i)}}print ""}' passwd# 搜索字符串"I am a student"中student子串的位置 echo "I am a student" | awk '{print index($0,"student")}' ->8

awk常用選項

選項含義
-v參數傳遞
-f指定腳本文件
-F指定分隔符
-V查看awk版本號
# 使用-v引用外部變量 num1=100 num2=200 awk -v var1="$num1" -v var2="$num2" 'BEGIN{print var1+var2}'

數組

awk中數組使用小括號包圍起來,每一項之間使用空格分隔,如:arr=("one" "two" "three" "four" "five").在awk中數組下標從1開始,需要注意哦~。 awk可以使用關聯數組這種數據結構,索引可以是數字或字符串。awk關聯數 組也不需要提前聲明其大小,因為它在運行時可以自動的增大或減小。

# 統計主機上所有的TCP,按照TCP狀態進行分類 netstat -an | grep tcp | awk '{array[$6]++}END{for(item in array){print item,array[item]}}' ->LISTEN 8 ->ESTABLISHED 26

awk文件處理

awk 可以直接處理目標文件,也可以通過“-f”讀取腳本對目標文件進行處理。

(1) awk 比較傾向于將一行分成多個“字段”然后再進行處理,且默認情況下字段的分隔符為空格或者 tab 鍵。awk 執行結果可以通過 print 的功能將字段數據打印顯示。在使用 awk 命令的過程中,可以使用

邏輯操作符如下所示:

*“&&”,表示“與”* *“||”,表示“或”* *“!”,表示“非”*

簡單的數學運算如下:

+、-、*、/、%、^分別 表示加、減、乘、除、取余和乘方

(2)在 Linux 系統中/etc/passwd 是一個非常典型的格式化文件,各字段間使用“:”作為分隔符隔開,Linux 系統中的大部分日志文件也是格式化文件,從這些文件中提取相關信息是運維的日常工作內容之一。

例如:需要查找出/etc/passwd 的用戶名、用戶 ID、組 ID 等列, 執行以下 awk 命令即可。

[root@localhost ~]# awk -F ':' '{print $1,$3,$4}' /etc/passwd root 0 0 bin 1 1 daemon 2 2 adm 3 4 lp 4 7 sync 5 0 shutdown 6 0 halt 7 0 mail 8 12 operator 11 0 games 12 100 ftp 14 50 //省略部分內容

awk 從輸入文件或者標準輸入中讀入信息,與 sed 一樣,信息的讀入也是逐行讀取的。不同的是 awk 將文本文件中的一行視為一個記錄,而將一行中的某一部分(列)作為記錄中的一個字段(域)。為了操作這些不同的字段,awk 借用 shell 中類似于位置變量的方法, 用$1、$2、$3?順序地表示行(記錄)中的不同字段。另外 awk 用$0 表示整個行(記錄)。不同的字段之間是通過指定的字符分隔。awk 默認的分隔符是空格。awk 允許在命令行中用“-F 分隔符”的形式來指定分隔符。因此,上述示例中,awk 命令對/etc/passwd 文件的處理過程如圖 所示:

awk工作原理圖

(3)awk 包含幾個特殊的內建變量(可直接用):

  • FS:指定每行文本的字段分隔符,默認為空格或制表位。
  • NF:當前處理的行的字段個數。
  • NR:當前處理的行的行號(序數)。
  • $0:當前處理的行的整行內容。
  • $n:當前處理行的第 n 個字段(第 n 列)。
  • FILENAME:被處理的文件名。
  • RS:數據記錄分隔,默認為n,即每行為一條記錄。

用法示例

(1)按行輸出文本

輸出所有內容

[root@localhost opt]# awk '{print}' test.txt //輸出所有內容,等同于 cat test.txt

或者

[root@localhost opt]# awk '{print $0}' test.txt //輸出所有內容,等同于 cat test.txt

輸出1-3行內容

[root@localhost opt]# awk 'NR==1,NR==3{print}' test.txt //輸出第 1~3 行內容 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin

或者

[root@localhost opt]# awk '(NR>=1)&&(NR<=3){print}' test.txt //輸出第 1~3 行內容 root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin

輸出以root 開頭的行

[root@localhost opt]# awk '/^root/{print}' /etc/passwd root:x:0:0:root:/root:/bin/bash

輸出以 nologin 結尾的行

[root@localhost opt]# awk '/nologin$/{print}' /etc/passwd bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin mail:x:8:12:mail:/var/spool/mail:/sbin/nologin operator:x:11:0:operator:/root:/sbin/nologin games:x:12:100:games:/usr/games:/sbin/nologin ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin nobody:x:99:99:Nobody:/:/sbin/nologin systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin dbus:x:81:81:System message bus:/:/sbin/nologin polkitd:x:999:998:User for polkitd:/:/sbin/nologin abrt:x:173:173::/etc/abrt:/sbin/nologin libstoragemgmt:x:998:996:daemon account for libstoragemgmt:/var/run/lsm:/sbin/nologin rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin colord:x:997:995:User for colord:/var/lib/colord:/sbin/nologin saslauth:x:996:76:Saslauthd user:/run/saslauthd:/sbin/nologin rtkit:x:172:172:RealtimeKit:/proc:/sbin/nologin pulse:x:171:171:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin chrony:x:995:991::/var/lib/chrony:/sbin/nologin rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin ntp:x:38:38::/etc/ntp:/sbin/nologin tss:x:59:59:Account used by the trousers package to sandbox the tcsd daemon:/dev/null:/sbin/nologin usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin geoclue:x:994:989:User for geoclue:/var/lib/geoclue:/sbin/nologin qemu:x:107:107:qemu user:/:/sbin/nologin radvd:x:75:75:radvd user:/:/sbin/nologin setroubleshoot:x:993:988::/var/lib/setroubleshoot:/sbin/nologin sssd:x:992:987:User for sssd:/:/sbin/nologin gdm:x:42:42::/var/lib/gdm:/sbin/nologin gnome-initial-setup:x:991:986::/run/gnome-initial-setup/:/sbin/nologin sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin avahi:x:70:70:Avahi mDNS/DNS-SD Stack:/var/run/avahi-daemon:/sbin/nologin postfix:x:89:89::/var/spool/postfix:/sbin/nologin tcpdump:x:72:72::/:/sbin/nologin apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin dhcpd:x:177:177:DHCP server:/:/sbin/nologin

統計以/bin/bash 結尾的行數,等同于 grep -c "/bin/bash$" /etc/passwd

[root@localhost opt]# awk 'BEGIN{X=0};//bin/bash$/{x++};END{print x}' /etc/passwd 11

統計以空行分隔的文本段落數

[root@localhost ~]# awk 'NEGIN{RS=""};END{print NR}' /etc/passwd 52

(2)按字段輸出文本

輸出每行中(以空格或制表位分隔)的第 3 個字段

[root@localhost ~]# awk '{print $3}' /etc/passwdManagement:/:/sbin/nologinbus:/:/sbin/nologinpolkitd:/:/sbin/nologinforcolord:/var/lib/colord:/sbin/nologinDaemon:/var/run/pulse:/sbin/nologinUser:/var/lib/nfs:/sbin/nologin User:/var/lib/nfs:/sbin/nologinbygeoclue:/var/lib/geoclue:/sbin/nologinsssd:/:/sbin/nologinStack:/var/run/avahi-daemon:/sbin/nologin[root@localhost ~]#

輸出每行中的第 1、3 個字段

[root@localhost ~]# awk '{print $1,$3}' /etc/passwd root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin sync:x:5:0:sync:/sbin:/bin/sync

輸出密碼為空的用戶的shadow 記錄

[root@localhost ~]# awk -F ":" '$2==""{print}' /etc/shadow

或者

[root@localhost ~]# awk 'BEGIN{FS=":"};$2==""{print}' /etc/shadow

輸出以冒號分隔且第 7 個字段中包含/bash 的行的第 1 個字段

[root@localhost ~]# awk -F ":" '$7~"/bash"{print $1}' /etc/passwd root shan lisi wangwu zhangsan liuliu c xiao jing tol jiji sfya

輸出包含 8 個字段且第 1 個字段中包含 nfs 的行的第 1、2 個字段

[root@localhost ~]# awk '($1~"nfs")&&(NF==8){print $1,$2}' /etc/services nfs 2049/tcp nfs 2049/udp nfs 2049/sctp netconfsoaphttp 832/tcp netconfsoaphttp 832/udp netconfsoapbeep 833/tcp netconfsoapbeep 833/udp

輸出第 7 個字段既不為/bin/bash 也不為/sbin/nologin 的所有行

[root@localhost ~]# awk -F ":" '($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' /etc/passwd sync:x:5:0:sync:/sbin:/bin/sync shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown halt:x:7:0:halt:/sbin:/sbin/halt

*(3)通過管道、雙引號調用 Shell 命令*

調用wc -l 命令統計使用bash 的用戶個數,等同于 grep -c "bash$" /etc/passwd

[root@localhost ~]# awk -F : '/bash$/{print | "wc -l"}' /etc/passwd 12

調用w 命令,并用來統計在線用戶數

[root@localhost ~]# awk 'BEGIN{while("w" | getline)n++;{print n-2}}' 4

調用hostname,并輸出當前的主機名

[root@localhost ~]# awk 'BEGIN{"hostname" | getline;print $0}' localhost.localdomain

總結

以上是生活随笔為你收集整理的awk 内嵌正则 提取字符串_干货-Shell编程文本处理三剑客之-awk的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。