awk-sed

 

1. awk 模式掃描和處理語言
  1.1 awk經常使用選項
  1.2 awk示例
	1.2.1 抽取2列
	1.2.2 tab鍵分割列
	1.2.3 篩選包含.html的行
	1.2.4 添加標題,添加內容,上面添加的內容被認爲爲1個字段,沒有tab分割
	1.2.5 拆分
	1.2.6 統計
	1.2.7 統計各個connection狀態
	1.2.8 每一個用戶的進程的佔了多少內存
	1.2.9 打印99乘法表
  1.3 awk內置變量
  1.4 print和printf
2. sed 用於過濾和轉換文本的流編輯器
  2.1 sed經常使用選項
  2.2 sed示例
	2.2.1 去掉html裏的tag
	2.2.2 去掉html裏的高度參數
  2.3 正則表達式的一些最基本的東西
3. 更多參考連接

曾經的上古神器。現在失落的藝術,正被Python等取代。html

  • awk (1977)用程序的方式分析文本 模式掃描和處理語言
  • sed (1975)用程序的方式編輯文本 用於過濾和轉換文本的流編輯器

1. awk 模式掃描和處理語言

簡單來講awk就是把文件逐行的讀入,以空格爲默認分隔符將每行切片,切開的部分再進行各類分析處理。
awk有3個不一樣版本: awk、nawk和gawk,未做特別說明,通常指gawk,gawk 是 AWK 的 GNU 版本。正則表達式

1.1 awk經常使用選項

POSIX options: GNU long options: (standard) shell

  • -f progfile --file=progfile 指定包含awk程序的文件progfile的路徑名。
  • -F fs --field-separator=fs 定義輸入字段分隔符。fs是一個字符串或者是一個正則表達式,如-F:。
  • -v var=val --assign=var=val 賦值一個用戶定義變量。

1.2 awk示例

1.2.1 抽取2列

$ ls -l |awk '{print $3,$9}'
toma t2.txt
toma temp.htmlexpress

1.2.2 tab鍵分割列

$ ls -l |awk '{print $3"\t"$9}'
toma t2.txt
toma temp.htmlapp

1.2.3 篩選包含.html的行

$ ls -l |awk -F: '/.html/'
-rw-r--r-- 1 toma users   28240 Apr  6 15:19 systemd.html
-rw-r--r-- 1 toma users   33323 Apr 10 23:23 temp.html

$ ls -l |awk '/.html/{print $3"\t"$9}'

以下3個等效
$ awk '/pci/{print $3"\t"$9}' hwinfo.txt
$ awk '/pci/{print $3,$9}' OFS="\t" hwinfo.txt
$ cat hwinfo.txt | awk '/pci/{print $3,$9}' OFS="\t"

/etc/passwd文件先指定:分割字段,再使用tab分隔輸出
$ awk -F ':' '{print $1"\t"$7}' /etc/passwd
$ awk -F ':' '{print $1,$7}' OFS="\t" /etc/passwd
$ awk -F ':' 'BEGIN {print "name,shell"} {print $1,$7} END {print "blue,/bin/nosh"}' OFS="\t" /etc/passwd
編輯器

1.2.4 添加標題,添加內容,上面添加的內容被認爲爲1個字段,沒有tab分割

$ awk -F ':' 'BEGIN {print "name","shell"} {print $1,$7} END {print "blue","/bin/nosh"}' OFS="\t" /etc/passwd

$ awk -F ':' 'BEGIN {print "name","shell"} {print $1,$7} {print "blue","/bin/nosh"} {print "blue2","/bin/nosh"}' OFS="\t" /etc/passwdide

1.2.5 拆分

$ ls -l |awk '{print > $2}' OFS="\t"
不指定列,僅拆分,原樣輸出,後面的OFS="\t"不起做用。
$ ls -l |awk '{print $2,$3,$5,$9}' OFS="\t" |awk '{print > $1}'
這樣便可tab分割後再拆分,或者:
ls -l |awk '{print $2,$3,$5,$9 > $2}' OFS="\t"

若第一列是標題,可參考以下方式
$ awk 'NR!=1{print > $2}' ss0.txt函數

1.2.6 統計

$ ls -l |awk '{sum+=$5} END {print sum}'
20639404
$ ls -l |awk '{sum+=$5} END {print "size is:",sum/1024/1024,"Mb"}'
size is: 19.6929 Mb
過濾4096大小的文件(通常都是文件夾)
$ ls -l |awk 'BEGIN {size=0;print "[start]size is ", size} {if($5!=4096){size=size+$5;}} END{print "[end]size is ", size/1024/1024,"M"}'
[start]size is  0
[end]size is  19.6499 Mui

1.2.7 統計各個connection狀態

$ awk 'NR!=1{a[$2]++;} END {for (i in a) print i ", " a[i];}' ss0.txt
ESTAB, 732
SYN-SENT, 2

$ awk '{sum[$1]+=1} END {for(k in sum) print k ":" sum[k]}' ss0.txt
$ awk '{sum[$1]+=1} END {for(k in sum) print k ":" sum[k]}' ss0.txt | sort -n -r -k 2 -t ':'this

1.2.8 每一個用戶的進程的佔了多少內存

$ ps aux | awk 'NR!=1{a[$1]+=$6;} END { for(i in a) print i ", " a[i]"KB";}'
systemd+, 2316KB
rtkit, 1920KB
polkitd, 14452KB
dbus, 3540KB
toma, 5678404KB
root, 269856KB

1.2.9 打印99乘法表

$ seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}'
1x1=1
1x2=2 2x2=4
1x3=3 2x3=6 3x3=9
1x4=4 2x4=8 3x4=12 4x4=16
1x5=5 2x5=10 3x5=15 4x5=20 5x5=25
1x6=6 2x6=12 3x6=18 4x6=24 5x6=30 6x6=36
1x7=7 2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49
1x8=8 2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64
1x9=9 2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81

1.3 awk內置變量

awk有許多內置變量用來設置環境信息,這些變量能夠被改變,下面給出了最經常使用的一些變量。

ARGC 命令行參數個數
ARGV 命令行參數排列
ENVIRON 支持隊列中系統環境變量的使用
FILENAME awk瀏覽的文件名
FNR 瀏覽文件的記錄數
FS 設置輸入域分隔符,等價於命令行 -F選項. 默認是空格或Tab
NF 瀏覽記錄的域的個數. 當前記錄中的字段個數,就是有多少列
NR 已讀的記錄數. 就是行號.
OFS 輸出域分隔符. 字段分隔符, 默認也是空格
RS 控制記錄分隔符. 默認爲換行符
ORS 輸出記錄分隔符. 默認爲換行符
$0 當前記錄(這個變量中存放着整個行的內容)
$1~$n 當前記錄的第n個字段,字段間由FS分隔

1.4 print和printf

awk中同時提供了print和printf兩種打印輸出的函數。

其中print函數的參數能夠是變量、數值或者字符串。字符串必須用雙引號引用,參數用逗號分隔。若是沒有逗號,參數就串聯在一塊兒而沒法區分。這裏,逗號的做用與輸出文件的分隔符的做用是同樣的,只是後者是空格而已。

printf函數,其用法和c語言中printf基本類似,能夠格式化字符串,輸出複雜時,printf更加好用,代碼更易懂。

$ awk -F ':' '{print "filename:" FILENAME ",linenumber:" NR ",columns:" NF ",linecontent:"$0}' /etc/passwd
$ awk -F ':' '{printf("filename:%10s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}' /etc/passwd

2. sed 用於過濾和轉換文本的流編輯器

2.1 sed經常使用選項

-n, --quiet, --silent suppress automatic printing of pattern space 抑制圖案空間的自動打印
--debug annotate program execution 註釋程序執行
-e script, --expression=script add the script to the commands to be executed 將腳本添加到要執行的命令中
-f script-file, --file=script-file add the contents of script-file to the commands to be executed 將script-file的內容添加到要執行的命令中
--follow-symlinks follow symlinks when processing in place 在處理時遵循符號連接
-i[SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if SUFFIX supplied) 編輯文件(若是提供SUFFIX,則進行備份)
-l N, --line-length=N specify the desired line-wrap length for the `l' command 爲`l'命令指定所需的換行長度
--posix disable all GNU extensions. 禁用全部GNU擴展。
-E, -r, --regexp-extended use extended regular expressions in the script (for portability use POSIX -E). 在腳本中使用擴展的正則表達式(爲了便攜性使用POSIX -E)
-s, --separate consider files as separate rather than as a single, continuous long stream. 將文件視爲單獨的而不是單個連續的長流。
--sandbox operate in sandbox mode (disable e/r/w commands). 在沙箱模式下運行(禁用e / r / w命令)
-u, --unbuffered load minimal amounts of data from the input files and flush the output buffers more often 從輸入文件加載最少許的數據並更頻繁地刷新輸出緩衝區
-z, --null-data separate lines by NUL characters 由NUL字符分隔的行
--help display this help and exit 顯示此幫助並退出
--version output version information and exit 輸出版本信息並退出

 

2.2 sed示例

用s命令替換
$ sed "s/my/Hao Chen's/g" pets.txt
注意:上面的sed並無對文件的內容改變,只是把處理事後的內容輸出,若是你要寫回文件,你可使用重定向,如:
$ sed "s/my/Hao Chen's/g" pets.txt > hao_pets.txt
或使用 -i 參數直接修改文件內容:
$ sed -i "s/my/Hao Chen's/g" pets.txt

在每一行最前面加點東西: #
$ sed 's/^/#/g' pets.txt

在每一行最後面加點東西: ---
$ sed 's/$/ --- /g' pets.txt

只替換第3行的文本。
$ sed "3s/my/your/g" pets.txt
只替換第3到第6行的文本。
$ sed "3,6s/my/your/g" pets.txt

只替換每一行的第一個s:
$ sed 's/s/S/1' my.txt

只替換每一行的第二個s:
$ sed 's/s/S/2' my.txt

只替換第一行的第3個之後的s:
$ sed 's/s/S/3g' my.txt

多個匹配
若是咱們須要一次替換多個模式,可參看下面的示例:(第一個模式把第一行到第三行的my替換成your,第二個則把第3行之後的This替換成了That)
$ sed '1,3s/my/your/g; 3,$s/This/That/g' my.txt
上面的命令等價於:(注:下面使用的是sed的-e命令行參數)
sed -e '1,3s/my/your/g' -e '3,$s/This/That/g' my.txt

2.2.1 去掉html裏的tags

$ sed 's/<[^>]*>//g' html.txt

錯誤示例: sed 's/<.*>//g' html.txt 會有問題. 上面的'[^>]' 指定了除了>的字符重複0次或屢次。

2.2.2 去掉html裏的高度參數

查找全部高度參數
$ grep height=\"..\" 1.html
<td align="left" height="20">RS</td>
<td align="left" height="23">ORS</td>

刪除表格內高度參數
$ sed 's/height=\"..\">/>/g' 1.html |grep align
<td align="left" >OFS</td>
<td align="left" >RS</td>
寫入文件
$ sed -i 's/height=\"..\">/>/g' 1.html

其餘命令及操做
a命令就是 append, i命令就是insert,它們是用來添加行的

Pattern Space (模式空間); Hold Space (保留空間)
注意: Append (附加) 與拷貝不一樣,會附加到目標位置原始內容換行後.

  • g: 將hold space中的內容拷貝到pattern space中,原來pattern space裏的內容清除
  • G: 將hold space中的內容append到pattern space\n後
  • h: 將pattern space中的內容拷貝到hold space中,原來的hold space裏的內容被清除
  • H: 將pattern space中的內容append到hold space\n後
  • x: 交換pattern space和hold space的內容

 


2.3 正則表達式的一些最基本的東西

 

^ 表示一行的開頭。 如:/^#/ 以#開頭的匹配。
$ 表示一行的結尾。 如:/}$/ 以}結尾的匹配。
\< 表示詞首。 如:\<abc 表示以 abc 爲首的詞。
\> 表示詞尾。 如:abc\> 表示以 abc 結尾的詞。
. 表示任何單個字符。  
* 表示某個字符出現了0次或屢次。  
[ ] 字符集合。 如:[abc] 表示匹配a或b或c,還有 [a-zA-Z] 表示匹配全部的26個字符。若是其中有^表示反,如 [^a] 表示非a的字符


3. 更多參考連接

https://coolshell.cn/articles/9070.html
AWK 簡明教程

內建變量,參看: http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din-Variables
流控方面,參看: http://www.gnu.org/software/gawk/manual/gawk.html#Statements
內建函數,參看: http://www.gnu.org/software/gawk/manual/gawk.html#Built_002din
正則表達式,參看:http://www.gnu.org/software/gawk/manual/gawk.html#Regexp

https://www.cnblogs.com/ggjucheng/archive/2013/01/13/2858470.html

https://coolshell.cn/articles/9104.html
SED 簡明教程
http://www.gnu.org/software/sed/manual/sed.html

https://zh.wikipedia.org/wiki/正則表達式
https://en.wikipedia.org/wiki/Regular_expression

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息