1. 程式人生 > >Linux基礎學習之Shell程式設計——字元擷取命令相關——printf、cut、awk、sed

Linux基礎學習之Shell程式設計——字元擷取命令相關——printf、cut、awk、sed

 

一、字元擷取命令之cut命令

1、字元擷取命令有哪些?

grep  cut    printf(嚴格來說不算)   awk   sed  命令

2、grep 是在檔案當中提取符合條件的行

      cut  是在檔案當中提取符合條件的列

3、cut命令:

[[email protected] ~]# cut 【選項】檔名

選項:

  -f  列號    :提取第幾列

  -d  分隔符:按照指定分隔符分隔列

注意:測試文件如下

[[email protected] sh]# vim student.txt

ID      Name    gender  Mark
1       Liming  M       86
2       Sc      M       90
3       Gao     M       83
~                    

注意 空白不是空格,而是製表符

[[email protected] sh]# cut -f 2 student.txt 
Name
Liming
Sc
Gao
[[email protected]
sh]# cut -f 2,3 student.txt Name gender Liming M Sc M Gao M [[email protected] sh]#

示例2、提取/etc/passwd 檔案中內容,用於練習-d選項

Gao	M
[[email protected] sh]# vim /etc/passwd

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
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
dbus:x:81:81:System message bus:/:/sbin/nologin
usbmuxd:x:113:113:usbmuxd user:/:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin
rtkit:x:499:499:RealtimeKit:/proc:/sbin/nologin
avahi-autoipd:x:170:170:Avahi IPv4LL Stack:/var/lib/avahi-autoipd:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
abrt:x:173:173::/etc/abrt:/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
haldaemon:x:68:68:HAL daemon:/:/sbin/nologin
[
[email protected]
sh]# cut -d ":" -f 1,3 /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 zhouxueli:500 sc:501 bimm:502 cangls:503 st:504 lamp:505 [[email protected] sh]#

4、字元擷取命令在程式設計中有什麼作用呢?

如果想要批量新增一定量的使用者,但是發現普通使用者不合要求,想刪除普通使用者,

所以可以根據擷取命令,把使用者名稱提取出來,之後根據使用者名稱刪除,

所以利用cut命令將使用者名稱批量提取,根據root取反,提取普通使用者,

編寫指令碼,利用迴圈,把這些使用者刪除

等等類似這種情形可用

5、cut命令的侷限[[email protected] ~]# df -h | cut -d " " -f 1,3

[[email protected] sh]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       18G  7.8G  8.5G  48% /
tmpfs                 931M   76K  931M   1% /dev/shm
/dev/sda1             477M   41M  411M   9% /boot
/dev/sdb1             2.0G  3.1M  1.9G   1% /disk1
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
/dev/sr0              1.1G  1.1G     0 100% /media/Ubuntu 14.04.5 LTS amd64
[[email protected] sh]#  df -h | grep "sda5"
[[email protected] sh]# df -h | grep "sdb5"
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
[[email protected] sh]# df -h | grep "sdb5" | cut -f 5
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
[[email protected] sh]# df -h | grep "sdb5" | cut -d "  " -f 5
cut: 分界符必須是單個字元
請嘗試執行"cut --help"來獲取更多資訊。
[[email protected] sh]# 
[[email protected] sh]# df -h | grep "sdb5" | cut -d " " -f 5

[[email protected] sh]# 

cut 命令不能將空格作為分隔符進行分隔,因為cut命令對空格的識別率較低

awk命令可以通過較為複雜的匹配規則進行處理該問題

建議cut命令能處理的儘量使用cut,而不是awk命令,awk 通常被稱為awk程式設計,awk有很多其他的功能

二、printf 命令:

1、printf  命令嚴格來說不是字元擷取命令,但是通常和cut命令放在一起用

,作為標準輸出;

2、printf 命令:

printf  '輸出型別輸出格式' 輸出內容

輸出型別:

  %ns:   輸出字串。n是數字指代輸出幾個字元

  %ni :    輸出整數。n是數字指代輸出幾個數字

  %m.nf : 輸出浮點數。m和n是數字,指代輸出的整數位數和小數位數。如%8.2f代表共輸出8位數,其中2位是小數,6位是整數。

輸出格式:

\a  :輸出警告聲音

\b:輸出退格鍵,也就是Backspace鍵

\f :清除螢幕

\n :換行

 \r :回車,也就是Enter鍵

 \t :水平輸出退格鍵,也就是Tab鍵

\v :垂直輸出退格鍵,也就是Tab鍵

[[email protected] sh]# printf %s 1 2 3 4 5 6
123456[[email protected] sh]# printf %s %s %s 1 2 3 4 5 6
%s%s123456[[email protected] sh]# printf '%s %s %s' 1 2 3 4 5 6
1 2 34 5 6[[email protected] sh]# printf '%s %s %s \n' 1 2 3 4 5 6
1 2 3 
4 5 6 
#如下,'%s %s %s\n'表示將內容按照後面的內容按照%s的個數為一組,然後換行,在此即表示三個一組,然後換行
[[email protected] sh]# printf  1 2 3 4 5 6
1 2 3
4 5 6
[[email protected] sh]# 
[[email protected] sh]# printf '%s' student.txt 
student.txt[[email protected] sh]# printf '%s' $(cat student.txt )
IDNamegenderMark1LimingM862ScM903GaoM83[[email protected] sh]# 

學習printf命令的原因是:

awk程式設計中無法直接呼叫系統中的cat 等命令,內容輸出需要用到printf 協助,所以在此學習

如上:

》printf '%s' $(cat student.txt)

#不調整輸出格式

》printf '%s\t %s\t %s\t %s\t %s\t %s\t \n' $(cat student.txt)

#調整格式輸出

[[email protected] sh]# cat student.txt 
ID	Name	gender	Mark
1	Liming	M	86
2	Sc	M	90
3	Gao	M	83

[[email protected] sh]# printf '%s\t %s\t %s\t %s\t %s\t %s\t \n' $(cat student.txt)
ID	 Name	 gender	 Mark	 1	 Liming	 
M	 86	 2	 Sc	 M	 90	 
3	 Gao	 M	 83	

3、在awk明星的輸出中支援print 和printf命令

》print:print會在每個輸出之後自動加入一個換行符(Linux預設沒有print命令)

》printf:printf是標準格式輸出命令,並不會自動加入換行符,如果需要換行,需要手工加入換行符;

三、awk命令:

1、cut命令只能使用製表符 冒號 逗號或者其他的,但不能用空格

   awk命令 可以實現cut命令所有的功能,awk命令經常被作為程式語言認識

2、awk命令格式:

# awk ‘條件1{動作1} 條件2{動作2} ...’  檔名

條件(Patterm):

 一般使用關係表示式作為條件

  x>10   判斷變數x是否大於10

  x>=10   大於等於

 x<=10    小於等於

動作(Action):

      格式化輸出    注意:格式調整建議使用雙引號括起來,而不是單引號

      流程控制語句

3、簡單示例:

示例文件:

[[email protected] sh]# vim student1.txt 

ID      Name    PHP     Linux   Mysql   Average
1       Liming  82      95      86      87.66
2       Sc      74      96      87      85.66
3       Gao     99      83      93      81.66
~                                                                                                  

示例1、注意:格式調整建議使用雙引號括起來,而不是單引號

[[email protected] sh]# awk '{printf $2 "\t" $6 "\n"}' student1.txt 
Name	Average
Liming	87.66
Sc	85.66
Gao	81.66
[[email protected] sh]# 

示例2:、空格作為分隔符時,awk的執行(cut命令無法將空格作為分隔符)

[[email protected] sh]# df -h | awk '{print $1 "\t" $5 "\t" $6}' 
Filesystem	Use%	Mounted
/dev/mapper/VolGroup-lv_root		
18G	/	
tmpfs	1%	/dev/shm
/dev/sda1	9%	/boot
/dev/sdb1	1%	/disk1
/dev/sdb5	1%	/disk5
/dev/sr0	100%	/media/Ubuntu
[[email protected] sh]# 

注:如上awk命令中裡面是有print 命令的,但Linux中沒有print命令

示例3、

[[email protected] sh]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       18G  7.8G  8.5G  48% /
tmpfs                 931M   76K  931M   1% /dev/shm
/dev/sda1             477M   41M  411M   9% /boot
/dev/sdb1             2.0G  3.1M  1.9G   1% /disk1
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
/dev/sr0              1.1G  1.1G     0 100% /media/Ubuntu 14.04.5 LTS amd64
[[email protected] sh]# 
[[email protected] sh]# df -h | grep sdb5
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
[[email protected] sh]# df -h | grep sdb5 | awk '{print $5}'
1%
[[email protected] sh]# df -h | grep sdb5 | awk '{print $5}' | cut -d "%" -f1
1
[[email protected] sh]# df -h | grep sdb5 | awk '{print $5}' | cut -d "%" -f 1
1
[[email protected] sh]# 

4、BEGIN命令

# awk 'BEGIN {printf "This is a transcript \n"}   {printf $2 "\t" $6 "\n"}' student1.txt

#如上表示在執行下面一行時,會先執行BEGIN後面跟著的第一個動作

[[email protected] sh]# awk 'BEGIN{print "test !!"} {print $2 "\t" $5}' student1.txt 
test !!
Name	Mysql
Liming	86
Sc	87
Gao	93
[[email protected] sh]# 
[[email protected] sh]# awk '{FS=":"} {print $1 "\t" $3}' /etc/passwd
root:x:0:0:root:/root:/bin/bash	
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
zhouxueli	500
sc	501
bimm	502
cangls	503
st	504
lamp	505
[[email protected] sh]# 

注意BEGIN的存在和執行結果第一行的區別

[[email protected] sh]# awk 'BEGIN{FS=":"} {print $1 "\t" $3}' /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
zhouxueli	500
sc	501
bimm	502
cangls	503
st	504
lamp	505
[[email protected] sh]# 

5、END命令

# awk 'END{printf "The End \n"} {printf $2 "\t" $6 "\n"}' student1.txt

#如上表示等待{printf $2 "\t" $6 "\n"}' student1.txt 執行完成後,再執行END 緊挨的動作

[[email protected] sh]# awk 'END{printf "The End \n"} {printf $2 "\t" $6 "\n"}' student1.txt 
Name	Average
Liming	87.66
Sc	85.66
Gao	81.66
The End 
[[email protected] sh]# 

6、FS內建變數  FS 用於定義分隔符的

# cat /etc/passwd | grep "/bin/bash" | \

awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'

#注意如上內容表示檢視檔案passwd檔案內的內容,把裡面帶如下字串/bin/bash 

的行 提取出來,然後將其中的第一列 第三列打印出來

[[email protected] sh]# cat /etc/passwd | grep "/bin/bash" | \
> awk 'BEGIN {FS=":"} {printf $1 "\t" $3 "\n"}'
root	0
zhouxueli	500
sc	501
bimm	502
cangls	503
st	504
lamp	505
[[email protected] sh]# 
[[email protected] sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[[email protected] sh]# cat student1.txt | grep -v Name | awk '$6 >=87 {printf $2 "\n"}'
Liming

awk程式設計可以通過shell程式設計進行處理,awk只用於處理字串的擷取

四、sed命令

1、grep 用於行擷取,cut 和awk 用於列擷取,而sed實際是用於流內容的編輯

2、sed 是一種幾乎包括在所有UNIX平臺(包括Linux)的輕量級流編輯器。

    sed 主要是用來將資料進行選取、替換、刪除、新增的命令。

vi 只能修改檔案中的內容,但是vi不能把某個命令的某個執行結果直接修改,必須要把

執行結果輸入到檔案中,才能修改。但是sed命令可以直接通過管道操作符將命令的

執行結果進行直接的選取、替換、刪除、新增的編輯。

3、sed命令的格式:

[[email protected] ~]# sed 【選項】‘[動作]'  檔名

選項:

 -n   :一般sed命令會把所有資料都輸出到螢幕,如果加入此選擇,則只會把經過sed命令處理的行輸出到螢幕

 -e :允許對輸入資料應用多條sed命令編輯

  -i  :用sed的修改結果直接修改讀取資料的檔案,而不是由螢幕輸出

動作:

a\  :追加,在當前行後新增一行或多行。新增多行時,除最後一行外,每行末尾需要用“\”代表資料未完成

c\  :行替換,用c後面的字串替換原資料行,替換多行時,除最後一行外,每行末尾需用“\”代表資料未完結。

i\  :插入,在當前行前面插入一行或多行。插入多行時,除最後一行外,每行末尾需要用“\”代表資料未完結。

d  :刪除,刪除指定的行。

p : 列印,輸出指定的行。

s   :字串替換,用一個字串替換另外一個字串。格式為“航範圍s/舊字串/新字串/g”(和vim 中替換格式類似)。

示例1:行資料操作

[[email protected] ~]# sed '2p' student1.txt

#檢視檔案的第二行

[[email protected] ~]# sed -n  '2p' student1.txt

[[email protected] sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[[email protected] sh]# sed '2p' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[[email protected] sh]# sed -n '2p' student1.txt 
1	Liming	82	95	86	87.66
[[email protected] sh]# 

示例2、刪除行資料操作

[[email protected] sh]# sed '2,4d' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
[[email protected] sh]# sed '2,3d' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
3	Gao	99	83	93	81.66
[[email protected] sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[[email protected] sh]# 

 示例3、

[[email protected] ~]# sed '2a hello' student1.txt

#在第二行後追加hello

[[email protected] ~]# sed '2i hello \

world ' student1.txt

#在第二行前插入兩行資料

[[email protected] sh]# sed '2i hello' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
hello
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[[email protected] sh]# sed '2i gao \
> world ' student1.txt
ID	Name	PHP	Linux	Mysql	Average
gao 
world 
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[[email protected] sh]# 

 示例4、

#sed '2c No such person ' student1.txt

#資料替換

[[email protected] sh]# sed '2c No such person ' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
No such person 
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[[email protected] sh]# 
[[email protected] sh]# df -h
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup-lv_root
                       18G  7.8G  8.5G  48% /
tmpfs                 931M   76K  931M   1% /dev/shm
/dev/sda1             477M   41M  411M   9% /boot
/dev/sdb1             2.0G  3.1M  1.9G   1% /disk1
/dev/sdb5             2.0G  3.1M  1.9G   1% /disk5
/dev/sr0              1.1G  1.1G     0 100% /media/Ubuntu 14.04.5 LTS amd64
[[email protected] sh]# 
[[email protected] sh]# df -h | sed -n '2p' 
/dev/mapper/VolGroup-lv_root

示例5、字串替換

#sed 's/舊字串/新字串/g' 檔名

#sed '3s/74/99/g' student1.txt

#在第三行中,把74換成99

#sed -i '3s/74/99/g' student1.txt

#sed 操作的資料直接寫入檔案

#sed -e 's/Liming//g;s/Gao//g' student1.txt

#同時把“Liming” 和“Gao”替換為空

[[email protected] sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[[email protected] sh]# sed '4s/99/55/g' student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	55	83	93	81.66
[[email protected] sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	99	83	93	81.66
[[email protected] sh]# sed -i '4s/99/55/g' student1.txt 
[[email protected] sh]# cat student1.txt 
ID	Name	PHP	Linux	Mysql	Average
1	Liming	82	95	86	87.66
2	Sc	74	96	87	85.66
3	Gao	55	83	93	81.66
[[email protected] sh]# 

注意對比上方的第四行第三列的資料變化,以及對比檔案內容在修改前後是否變化。

建議需要修改檔案時使用vim 命令,不需要修改檔案時,使用sed命令