L-1-23 awk&sed
awk <option> '<PATTERN> {<action>}' <filename> [<filename2> ...] //文本處理工具
比如:df -Ph |awk '{print $1,$3}'
//awk中大括號中應該用雙引號
awk會去分割每行並成分為字段,如:
this is a cat.
$1 $2 $3 $4
$4就是cat.
$0代表這一整行
******************<option>******************
-F<interpunction> //指定分隔符,可以用雙引號括起來
比如:awk -F: {print $1,$3} /etc/passwd //passwd文件中字段是由:分開的而不是由空格分開的。多個分割符連在一起時只算一個。(cut是算多個)
-v <var>="<string>" //awk可以設置內置變量,-v用來設置內置變量
也可以這樣表達awk 'BEGIN{a="Hello"};{print a}' //這裏多語句用;分開
*****************內置變量******************* //內置變量在大括號中直接寫,雙引號內的是字符串
FS 輸入分割符,默認是空格
OFS 輸出分割符,寫print命今時,$<num>之間用,分開的,默認是空格,但改後就有變化
如:awk -F: '{OFS="#"}{print $1,$2}' /etc/passwd
RS 輸入換行符,默認是回車
ORS 輸出換行符,默認是回車
FNR 當前處理文件的行數,單文件時處理到第幾行就是第幾行。
NR 所有文件處理的行數,用於多文件時使用
如:awk 'END{print NR}' /etc/passwd /etc/fstab //顯示passwd和fstab一共幾行
NF 當前處理行的分割成的字段數。$NF是當前行的最後一個字段
*****************<PATTERN>**************** //類似於sed的address,決定需要操作的行
/<RegExp>/ //正則表達式,要用斜杠括起來,只對符合條件的行進行操作
如:awk -F: '/r..t/{print $1}' /etc/passwd //以包含/r..t/表達式的行作為目標,將它們打印出來
<expression> //表達式,只對符合條件的行進行操作
如:awk -F: '$3 >= 500{print $1,$3}' /etc/passwd //在passwd文件中$3代表UID,這裏比較UID是否大於500,並打印出大於500的用戶名和UID
如:awk -F: '$7~bash${print $1,$7}' /etc/passwd //在passwd文件中$7是用戶的shell,這裏判斷$7是否以bash結尾,並打印出符合條件的用戶名與用的shell
<range> //指定範圍,與sed的指定範圍不太一樣。
{BEGIN|END} //表示命今只在開始或結束前施行一次。有了這個PATTERN,awk命令後面可以不跟文件
如:awk 'BEGIN{print "one\ntwo\nthree"}' //\n是換行符
<null> //什麽都不寫表示讀取所有行
********************表達式*********************
計算操作 用法如:awk 'BEGIN{print 1+1}'
有以下幾種:
-<num> 取負值
+<figure> 將非數字改成數字,boolean中是為1,否為0
如:awk 'BEGIN{a=+(6 > 7);print a}' 結果是0
awk 'BEGIN{a=+(7 > 6);print a}',結果是1
還有一些計算符與shell一致:+-*/^(次方)%(取余)
賦值操作符,用法如:awk 'BEGIN{i++;print i}'
這些與shell一致:= += -= *= /= ^= %= ++ --
布爾值,結果是True或False
如:< > == <= >=
!=(不等)
<string> ~ <pattern> //<string>是否滿足<pattern>,滿足為True
<string> !~ <pattern> //<string>是否滿足<pattern>,不滿足為True
邏輯關系符
和shell一樣:&& ||
條件表達式
<selector>?<if-true>:<if-false> //三目結構,判斷<selector>,結果為真值為<if-ture>,否則為<if-false>
如:awk 'BEGIN{a=3;b=4;max=a>b?a:b;print max}'
********************數組*************************
例子:awk -F: '{shell[$NF]++}END{for(A in shell){print A,shell[A]}}' /etc/passwd
這個數組裏第一個讀出的數組是shell[/bin/bash]這是中括號裏的下標可以是任何字符串,++代表shell[/bin/shell]的值變成1
第二行得到shell[/sbin/nologin]++,最後的循環時可以打印出下標A,這裏是下標/bin/bash,而shell[A]是/bin/bash用戶個數
******************<action>************************
print <item> 打印指定字段
如:awk -F: '{print $1}' /etc/passwd
awk -F: '{print NF}' /etc/passwd //參數NF不用打括號
awk 'BEGIN{print "Hello"}'
printf <format>,<item1>
%c ASCII碼形式顯示
%d,%i 十進制整數
%e,%E 科學計數法
%f 浮點數形式顯示
%g,%G 科學計數法浮點數形式顯示
%s 字符串形式表示
%u 無符號整數
%% %自身
修飾符
<num> 以<num>個數字來表示
- 左對齊 //不寫默認為右對齊
用法:awk -F: '{printf "%-15s %i\n",$1,$3}' /etc/passwd
%-15s是$1的格式,%i是$3,\n是換行
if <condition> <then> else <else_than>
如:awk -F: '{if ($1=="root") print $1;else print "not root"}' /etc/passwd
while <condition> {<command>;[<command> ..]}
如:awk -F: '{i=1;while(i<=3){print$i;i++}}' /etc/passwd
do-while {<command>} while <condition>
如:awk -F: '{i=q;do{print$i;i++}while(i<=3)}' /etc/passwd
for
如:awk -F: '{for(i=1;i<=3;i++)print$i}' /etc/passwd
case switch(<condition>) {case {<var>|<regexp>}:<command> [...] default:<command> }
break,continue 用法類似bash
next跳過當前行,直接進行下一行
如:awk -F: '{if($3%2==0)next;print $1;$3}' /etc/passwd
-------------------------------------------------------------------------------------------------------------------------------------------
[sed]
sed '<AdressCommand>' <file> 流編輯器
-n 靜默模式,不在模式空間的內容。(只顯示修改的內容)
比如 sed '1p' /etc/passwd 結果是輸出第一行後再打輸出passwd文件
sed -n '1p' /etc/passwd 結果是只輸出第一行
-i 直接修改原文件
-e '<SCRIPT>' [-e <script>] ... :同時執行多個sed腳本
-f <file> :通過讀取一個文件來讀取裏面的sed腳本
-r 使用擴展正則表達式。
Address: //Address是選擇須要修改的行,Command是設置做什麽
1. StartLine,EndLine
eg: 1,100
//$表示最後一行,$-n表示最後第n行。
比如:sed '1,100d' <filename> //刪除<filename>的1-100行。
sed '1,$-3d' <filename> //比如一共5行,最後的第三行正好是第三行,所以是刪除前1-3行。
2. /RegExp/
eg: /^root/
//正則表達式來代表符合條件的行
比如:sed '/^root/d' <filename> //刪除文件中以root開頭的行
sed '/oot/d' /etc/passwd //刪除文件中帶有oot字符的行
3. /pattern1/,/pattern2/
//第一次被pattern1匹配到的行,至第一次被pattern2匹配到的行結束,中間的所有行進行操作。
比如:sed -n '/^root/,/^nobody/p' /etc/passwd //輸出root開頭的行到nobody開頭的行
4.LineNumber
//指精確的行
比如:sed '1d' <filename> //刪除第一行
5.StartLine,+N
//從startLine開始,向後的N行。共N+1行。
比如:sed -n '1,+3p' /etc/passwd //輸出passwd文件的第一行與接下來的三行。
sed '/^root/,+3a \hello' /etc/passwd //在passwd文件以root開頭的行,與此行接下來的3行下都追加hello
Command:
d:刪除符合條件的行。
p:顯示符合條件的行。
a \<string>:在指定的行後面追加新行,內容為“<string>”(\n 換行符)
比如:sed '/^root/,+3a \hello' /etc/passwd //在passwd文件以root開頭的行,與此行接下來的3行下都追加hello
sed '1,3a first line\nsecond line' /etc/passwd //在文件1-3行下各添加兩行first line second line
i \<string>:在指定的行前面追加新行,內容為“<string>”,與a類似。
r <file>: 將指定的文件內容添加至符合條件的行處
比如:sed '1r /etc/fstab' /etc/passwd //把fstab內容添加到passwd第一行下
w <file>: 將指定範圍內的內容另存為至指定文件。
s/<pattern>/<string>/<※> 查找每一行符合條件的<pattern>(能用正則表達式),並將每行中第一次匹配到的串替換成<string>。寫了s就不用寫address了,默認修改每一行。
※:g:全局替換。 //即替換所有,而不是每行第一個
i:忽略大小寫
eg:sed 's/oot/OOT/'/etc/fstab
eg:sed -r 's@^[[:space:]]+#@@g' /etc/inittab //s不一定是s///,也可以是s@@@、s###等其他特殊字符
string這裏可以使用&,代表了引用匹配的條目。
比如:正則表達式l..e,可能是like或是love,要它們匹配後都加r,那麽該寫成's/l..k/&r/',&代表了匹配的文字,它可以在任何地方,r&,1&1
sed 's#l\(..e\)#L\1#g' <filename> //只改括號內的部分,用了括號第二部分就可以引用。
比如說adress是2,command是p,那麽2p就是第二行的意思,sed -n '2p' <filename> 就是讀取文件的第二行。
如果需要修改的字符是特殊字符,那麽就需要\符轉譯:sed '/^\//d' /etc/fstab 刪除/開頭的行,其中\是特殊字符。
L-1-23 awk&sed