LinuxShell之字符截取和替換命令


一 cut提取命令

  cut命令的默認分割符是制表符,也就是"tab"鍵

 

 

 二 printf格式化輸出

 

 

 三 awk編程

   1 awk基本使用

 

 awk [-F|-f|-v] ‘BEGIN{} //{command1; command2} END{}’ file
 [-F|-f|-v]   大參數,-F指定分隔符,-f調用腳本,-v定義變量 var=value

 

[root@hang ~]# cat student.txt 
ID      Name    PHP     Linux   MySQL   Average
1       LiMing  82      95      86      87.66
2       Sc      74      96      87      85.66
3       Tg      99      83      93      91.66
練習數據:student.txt
[root@hang ~]# awk '{printf $2 "\t" $6 "\n"}' student.txt 
Name    Average
LiMing  87.66
Sc      85.66
Tg      91.66
示例

 2 awk的條件

 

 

  2.1 BEGIN

  BEGIN是awk的保留字,是一種特殊的條件類型. BEGIN的執行時機是"awk程序一開始時,尚未讀取任何數據之前執行".一旦BEGIN后的動作執行一次,當awk開始從文件中讀入數據,BEGIN的條件就不在成立,所以BEGIN定義的動作只能被執行一次.

[root@hang ~]# awk 'BEGIN{printf "This is a transcript \n"}  {printf $2 "\t" $6 "\n"}' student.txt 
This is a transcript 
Name    Average
LiMing  87.66
Sc      85.66
Tg      91.66

#awk命令只要檢測不到完整地單引號就不會執行,所以這個命令的換行不用加入"\"就是一行命令
#這里定義了兩個動作
#第一個動作使用BEGIN條件,所以會在讀入文件數據前打印"這是一張成績單"(只會執行一次)
#第二個動作會打印文件的第二個字段和第六個字段
示例

 2.2 END

END也是awk保留字,不過剛好和BEGIN相反.END是在awk程序處理完所有數據,即將結束時執行.END后的動作只在程序結束時執行一次

[root@hang ~]# awk 'END{printf "The End \n"} {printf $2 "\t" $6 "\n"}' student.txt 
Name    Average
LiMing  87.66
Sc      85.66
Tg      91.66
The End 
示例

2.3 關系運算符

[root@hang ~]# cat student.txt |grep -v Name | awk '$6 >= 87 {printf $2 "\n"}'
LiMing
Tg

#使用cat輸出文件內容,用grep取不包含"Name"的行
#判斷第六個字段(平均成績)大於等於87分的行.如果判斷成立,則打印第六列(學院名)
示例1:查看平均成績大於等於87分的學員是誰

 加入了條件之后,只有條件成立動作才會執行,如果條件不滿足,則動作則不運行.通過這個實驗,可以發現,雖然awk是列提取命令,但是也要按行來讀入的.這個命令的執行過程是這樣的:

①如果有BEGIN條件,則先執行BEGIN定義的動作;

②如果沒有BEGIN條件,則讀入第一行,把第一行的數據一次賦予$0,$1,$2等變量.其中$0代表此行的整體數據,$1代表第一字段,$2代表第二字段.

③依據條件類型判斷動作是否執行.如果條件符合,則執行動作,否則讀入下一行數據.如果沒有條件,則每行都執行動作.

④讀入下一行數據,重復執行上述步驟.

[root@hang ~]# awk '$2 ~ /Sc/ {printf $6 "\n"}' student.txt 
85.66
示例:查看Sc用戶的平均成績

2.4 正則表達式

若想讓awk識別字符串,必須使用"//"包含,例如:

[root@hang ~]# awk '/LiMing/ {print}' student.txt 
1       LiMing  82      95      86      87.66
打印用戶LiMing的信息
[root@hang ~]# df -h |awk '/sda[0-9]/ {print $1 "\t" $5 "\t"}'
/dev/sda2       20%
/dev/sda1       22%
用df命令查看分區使用情況時,若只想查看真正的系統分區的使用情況,而不像查看光盤和臨時分區的使用情況

2.5 awk內置變量

 

 

 

[root@hang ~]# cat /etc/passwd|grep "/bin/bash" | awk ' BEGIN {FS=":"} {printf $1 "\t" $3 "\t 行號:" NR "\t 字段數:" NF "\n"}'
root    0        行號:1  字段數:7

#開始執行{分隔符是":"}{輸出第一字段和第三字段 輸出行號(NR值) ziduans(NF值)}
查詢可以登錄的用戶的用戶名和UID,並查詢行號即及字段數
[root@hang ~]# cat /etc/passwd | awk 'BEGIN {FS=":"} $1=="sshd" {print $1 "\t" $3 "\t 行號:" NR "\t 字段數:" NF "\n"}'
sshd    74       行號:32         字段數:7
查詢sshd這個偽用戶的相關信息

2.6 awk流程控制

[root@hang ~]# awk 'NR==2{php1=$3} NR==3{php2=$3} NR==4{php3=$3;total=php1+php2+php3;print "total php is:" total}' student.txt 
total php is:255
統計php成績總分

在awk編程中,因為命令的語句過長,在輸入格式時需要注意一下內容:

①多個條件{動作}可以用空格分隔,也可以用回車分隔.

②在一個動作中,如果需要執行多個命令,需要用";"分隔,或用回車分隔.

③在awk中,變量的賦值與調用都不需要加入"$"符.

④條件中判斷兩個值是否相同,請使用"==",以便和變量賦值進行區分.

[root@hang ~]# awk '{if (NR>=2) {if ($4>=90) print $2 " is a good man!\n"}}' student.txt 
LiMing is a good man!

Sc is a good man!
方法1:若Linux成績大於90,就是一個好男人
[root@hang ~]# awk 'NR>=2 {test=$4} test>=90 {print $2 " is a good man!\n"}' student.txt 
LiMing is a good man!

Sc is a good man!
方法2:若Linux成績大於90,就是一個好男人

2.7 awk函數

awk編程允許在編程時使用函數,awk函數的定義方法如下:

[root@hang ~]# awk 'function test(a,b) {printf a "\t" b "\n"}   {test($2,$6)}' student.txt 
Name    Average
LiMing  87.66
Sc      85.66
Tg      91.66
使用函數打印student.txt的學員姓名和平均成績

2.8 awk中調用腳本

 當程序是多行時,使用外部腳本是合適的.首先在外部文件中寫好腳本,然后使用awk的-f選項,使其讀入腳本並執行.

BEGIN {FS=":"} {print $1 "\t" $3}
pass.awk
[root@hang ~]# awk -f pass.awk /etc/passwd
root    0
bin     1
daemon  2
adm     3
lp      4
sync    5
shutdown        6
halt    7
mail    8
uucp    10
operator        11
games   12
gopher  13
ftp     14
nobody  99
dbus    81
usbmuxd 113
rpc     32
rtkit   499
avahi-autoipd   170
vcsa    69
abrt    173
rpcuser 29
nfsnobody       65534
haldaemon       68
ntp     38
apache  48
saslauth        498
postfix 89
gdm     42
pulse   497
sshd    74
tcpdump 72
調用pass.awk腳本

四 sed命令

   sed命令主要是用來將數據進行選取,替換,刪除,新增的命令

 

 

 

 注意:sed所做的修改並不會直接改變文件的內容,而是把修改結果只顯示到屏幕上,除非用"-i"才會直接修改文件

 行數數據操作

[root@hang ~]# sed -n '2p' student.txt 
1       LiMing  82
查看第二行數據
#刪除第二行到第四行數據
[root@hang ~]# sed  '2,4d' student.txt 
ID      Name    PHP     Linux   MySQL   Average

#但是本身文件並沒有修改,除非使用"-i"
[root@hang ~]# cat student.txt 
ID      Name    PHP     Linux   MySQL   Average
1       LiMing  82      95      86      87.66
2       Sc      74      96      87      85.66
3       Tg      99      83      93      91.66
[root@hang ~]
刪除文件數據
[root@hang ~]# sed -n '2i hello \
world' student.txt
hello 
world

#-n 只查看sed命令操作的數據,而不是查看所有數據
在指定行追加多行數據
[root@hang ~]# sed '2i hello \
> world' student.txt
ID      Name    PHP     Linux   MySQL   Average
hello 
world
1       LiMing  82      95      86      87.66
2       Sc      74      96      87      85.66
3       Tg      99      83      93      91.66
在指定的行后面追加數據
[root@hang ~]# cat aaa.txt 
ID      Name    PHP     Linux   MySQL   Average
2       Sc      74      96      87      85.66
3       Tg      99      83      93      91.66
[root@hang ~]# sed -i '2c No such person' aaa.txt 
[root@hang ~]# cat aaa.txt 
ID      Name    PHP     Linux   MySQL   Average
No such person
3       Tg      99      83      93      91.66
[root@hang ~]# 
替換指定行的數據

字符串替換

"c"動作是進行整行替換的,若僅僅想替換行中的部分數據,就要使用"s"動作了,s動作格式是:

sed 's/舊字符串/新字符串/g' 文件名
[root@hang ~]# cat aaa.txt 
ID      Name    PHP     Linux   MySQL   Average
1       LiMing  82      95      86      87.66
2       Sc      74      96      87      85.66
3       Tg      99      83      93      91.66
#這里使用正則表達式,"^"代表行首
[root@hang ~]# sed -i '4s/^/#/g' aaa.txt 
[root@hang ~]# cat aaa.txt 
ID      Name    PHP     Linux   MySQL   Average
1       LiMing  82      95      86      87.66
2       Sc      74      96      87      85.66
#3      Tg      99      83      93      91.66
示例
[root@hang ~]# sed -e 's/LiMing//g;s/Tg//g' aaa.txt 
ID      Name    PHP     Linux   MySQL   Average
1               82      95      86      87.66
2       Sc      74      96      87      85.66
#3              99      83      93      91.66


#-e選項可以同時執行多個sed動作,多個動作之間要用";"號或回車分隔

[root@hang ~]# sed -e 's/LiMing//g
> s/Tg//g' student.txt
ID      Name    PHP     Linux   MySQL   Average
1               82      95      86      87.66
2       Sc      74      96      87      85.66
3               99      83      93      91.66
同時執行多個sed操作

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM