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命令