《LinuxShell腳本攻略》筆記,Chap-2:命令之樂
簡介
各種命令可謂Unix-Like系統(tǒng)中優(yōu)美的部分养盗,它能幫我們搞定各種繁雜的任務(wù)缚陷。
一旦你嘗試過Linux提供的這些利器,你一定會感到驚訝:以前沒有這些命令的時候爪瓜,自己是什么熬過來的蹬跃。
最鐘愛的莫過于 grep
, awk
, sed
, find
命令了!
本章將會為你介紹一些最有趣同時也是最實用的命令铆铆。
用cat進行拼接
#cat命令通常用于讀取蝶缀、顯示或拼接文件內(nèi)容,不過它所具備的能力遠不止此
#cat(concatenate, 拼接)
cat file1 file2 ···
echo "Ahaha" | cat - file1 file2 #-指stdin文本文件名
cat -s file3 -- cat file3 | tr -s '\n' #壓縮空白行
cat -T test.py #將制表符顯示為 ^I, 避免制表符和連續(xù)空格誤用, 產(chǎn)生錯誤縮進
cat -n file4 #顯示行號
錄制與回放終端會話
當(dāng)你需要準備一個命令行教程時薄货,如果將我們輸入命令后的一切按照先后次序記錄下來翁都,再進行回放,是不是很nice谅猾!
通過 script
, scriptreplay
命令, 把終端會話記錄到文件柄慰,并回放鳍悠。
#-t,將時間數(shù)據(jù)輸出到標準錯誤; -a,追加輸出
script -t 2> timing.log -a output.session #兩個文件隨意取名, 如不將錯誤重定向會顯示在屏幕上導(dǎo)致很亂
輸入命令
cmd2
···
exit #退出錄制
scriptreplay -t timing.log output.session #播放
文件查找與文件列表
find
是Unix/Linux命令行工具箱中最棒的工具之一坐搔。
find
命令沿著文件層次結(jié)構(gòu)向下遍歷藏研,匹配符合條件的文件,并執(zhí)行相應(yīng)的操作概行。
#基于文件名及正則表達式搜索
find /home/zhang #列出/home/zhang目錄及其子目錄線所有文件和文件夾
find /home/zhang -name "*.txt"
find . -name "*.sh" -o -iname "zhang*" #匹配多個
find /home/zhang -path "201710*" #-path將文件路徑作為一個整體進行匹配
find . -regex ".*\(\.txt|\.[0-9]+\)$" #匹配以.txt或數(shù)字結(jié)尾的文件
#使用-maxdepth, -mindepth參數(shù)蠢挡,來限制find的遍歷深度
#-type, 根據(jù)文件類型搜索。 f(普通文件)凳忙,d(目錄)业踏,b(塊設(shè)備),l(符號鏈接)涧卵,s(套接字)等
find /home -maxdepth 1 -type f(d) #參數(shù)順序也會影響find的查找效率
#根據(jù)文件類型搜索
find /dev -type b #查看/dev及其子目錄下設(shè)備文件
find / -maxdepth 1 -type l #查找/下鏈接文件
#根據(jù)文件時間進行搜索
#Unix/Linux文件系統(tǒng)中的每一個文件都有三種時間戳(timestamp),-表示小于勤家,+表示大于
#Unix中并沒有所謂的 "創(chuàng)建時間" 的概念
#訪問時間(-atime,以天為單位; -amin,以分鐘為單位):用戶最近一次訪問文件時間柳恐;
#修改時間(-mtime,以天為單位伐脖; -mmin,以分鐘為單位):文件最后一次修改時間;
#變化時間(-ctime,以天為單位胎撤; -cmin,以分鐘為單位):文件元數(shù)據(jù)(如權(quán)限晓殊,所有權(quán))最后一次變化時間;
find /home/zhang -type f -mtime 7 #7天前被修改的普通文件
find /home/zhang -type f -amin -10 #搜索10分鐘內(nèi)被修改的普通文件
find . -type f -newer file1.txt #找出比file1.txt新的文件
#基于文件大小的搜索
#b(塊伤提,512字節(jié)), c(字節(jié)), w(字,2字節(jié)), k(千字節(jié)), M(兆字節(jié)), G(吉字節(jié))
find . -type -f -size +100k
#刪除匹配的文件
find . -type f -name "*.swp" -delete
#基于文件權(quán)限和所有權(quán)的匹配
find . -type f -perm 644
find /var/apache -type f -name "*.php" -perm 644 #搜索基于權(quán)限的文件
find /var -maxdepth 2 -type f -user zhang #搜索基于用戶的文件
#執(zhí)行命令或動作
#find命令可以借助-exec與其他命令進行結(jié)合
#{}是一個特殊字符串认烁,將替換為相應(yīng)文件名
find . -type f -perm 764 -user zhang -exec chmod 644 {} \; #將所屬用戶zhang肿男,權(quán)限764的文件權(quán)限修改為644
find . -type f -mmin +30 -name "*.txt" -exec cp {} {}.old \; #復(fù)制最近30內(nèi)修改的名字為.txt的文件
#-exec結(jié)合多個命令
#我們無法在-exec參數(shù)中直接使用多個命令,不過我們可以把多個命令寫到一個shellscript中却嗡,然后執(zhí)行
-exec ./test.sh {} \;
find . -type f -name "*.sh" -mmin -10 -exec sh {} \;
#讓find跳過特定目錄
-prune
利用stat
命令查看atime, mtime, ctime :
#stat - display file or file system status
stat 1.txt
#Access:
#Modify:
#Change:
利用touch
命令修改atime, mtime, ctime:
#touch - change file timestamps
#-a change only the access time
#-m change only the modification time
#-d instead of current time
#-t instead of current time
玩轉(zhuǎn)xargs
xargs能夠處理stdin并將其轉(zhuǎn)換為特定命令的命令行參數(shù)舶沛,也可以將單行或多行輸入文本轉(zhuǎn)換成其他格式(如多行變單行)。
cmd | xargs
#將多行輸入轉(zhuǎn)換為單行輸出
echo -e "1\n2\n3" | xargs #將換行符替換為空格
#將單行輸入轉(zhuǎn)換成多行輸出
echo "1 2 3" | xargs -n 1 #每行一個參數(shù)
echo "hahaZhahaZhahaZhaha" | xargs -n 2 -d Z #-d指定分隔符
#讀取stdin窗价,將格式化參數(shù)傳遞給命令
cat test.txt | xargs -n 1 ./zhang.sh #zhang.sh arg1; zhang.sh arg2... 每次提供一個參數(shù)
cat test.txt | xargs -n X ./zhang.sh #X為參數(shù)個數(shù)如庭,一次提供全部參數(shù)
#指定替換字符串
cat test.txt | xargs -I {} ./zhang.sh {}
#結(jié)合find使用xargs
find . -type f -name "*.txt" -print0 | xargs -0 ls #-print0無換行輸出, -0將\0作為輸入界定符
#統(tǒng)計某文件行數(shù)
find /path -type f -name "*.c" -print0 | xargs -0 wc -l
#結(jié)合stdin,運用while和子shell
cat file.txt | while read arg; do cat $arg; done == cat file.txt | xargs - {} cat {}
cmd0 | (cmd1; cmd2; cmd3) | cmd4 #子shell
用tr進行轉(zhuǎn)換
#tr - translate or delete characters
#tr命令經(jīng)常用來編寫優(yōu)美的單行命令
#tr可對來自stdin的字符 進行替換撼港、刪除以及壓縮
echo "AH WONDERFUL" | tr 'A-Z' 'a-z' #轉(zhuǎn)換大小寫
echo "AH WONDERFUL" | tr 'A-Z' 'a-b' --> ab bbbbbbbbb
#tr [option] set1 set2
#如果兩個字符集長度不相等坪它,那么set2會不斷重復(fù)其最后一個字符,直到長度與set1相同
echo 12345 | tr '0-9' '9876543210' #數(shù)字加密
echo 87654 | tr '9876543210' '0-9' #數(shù)字解密
echo 'He is a cool boy, and she is a beautiful girl' | tr 'A-Za-z' 'NOPQRSRUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm' #加密
echo 'Ur vf n pbby obl, naq fur' | tr 'NOPQRSRUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm' 'A-Za-z' #解密
cat 1.txt | tr '\t' ' ' #將制表符轉(zhuǎn)換為空格
#刪除字符
echo "Hello 530 World" | tr -d '0-9' #-d刪除帝牡,刪除數(shù)字
Hello World
echo "Hello 520 World" | tr -d -c '0-9' #-c補集
520
#壓縮字符往毡,將連續(xù)的重復(fù)字符壓縮為單個字符
echo "GNU's not Unix" | tr -s ' ' #-s壓縮,壓縮空格
GNU's not Unix
echo -e "1\n2\n3\n4\n5" > sum.txt
cat sum.txt | echo $[ $(tr '\n' '+') 0 ] -- echo $[1+2+3+4+5+0]
#tr字符類
\a 終端鳴響
\b 退格
\f 換頁
\n 換行
\r 回車
\t 水平制表符
\v 垂直制表符
string1-stringN #從字符1到字符N升序過程中的所有字符
[字符*次數(shù)]
[:alnum:] #所有字母和數(shù)字
[:alpha:] #所有字母
[:digit:] #所有數(shù)字
[:lower:] #所有小寫字母
[:upper:] #所有大寫字母
[:graph:] #所有可打印字符靶溜,不含空格
[:print:] #所有可打印字符开瞭,包含空格
[:blank:] #所有水平排列的空白字符
[:cntrl:] #所有控制字符
[:punct:] #所有標點字符
[:space:] #所有空白字符
[:xdigit:] #所有十六進制數(shù)
[=字符] #指定字符
校驗和 與 核實文件完整性
#校驗和(checksum)程序從文件中生成校驗和密鑰懒震,然后利用校驗和密鑰核實文件的完整性
#校驗和對于編寫備份腳本或系統(tǒng)維護腳本非常重要,因為它們都會涉及通過網(wǎng)絡(luò)傳輸文件
#通過使用校驗和核實嗤详,我們就可以識別那些在網(wǎng)絡(luò)傳輸過程中出現(xiàn)損壞的文件个扰,并重傳,從而確保數(shù)據(jù)完整性
#校驗和對于核實數(shù)據(jù)完整性非常有用
#廣泛使用的校驗和技術(shù)有:md5sum, sha1sum
#對單個文件進行校驗
md5sum sum.txt > sum.md5
#302c28003d487124d97c242de94da856 sum.txt
md5sum -c sum.md5 #-c檢查
#sum.txt: 確定
#對目錄進行校驗
#對目錄計算校驗和意味著我們需要對目錄中的所有文件以遞歸的方式進行計算
yum install -y md5deep
md5deep -r ./dir > dir.md5 #recursive遞歸
md5sum -c dir.md5
#可以將測試dir下某個文件更改一下葱色,校驗的時候會報錯
排序递宅、單一、重復(fù)
#sort - 對文本文件進行行排序
#uniq - 刪除排序文件中的重復(fù)行
echo -e "333\n1" > 1.txt; echo -e "22\n22" > 2.txt
sort 1.txt 2.txt -o ./soredt.txt
#1
#22
#22
#333
cat sortec.txt | uniq
#1
#22
#333
sort -n #按數(shù)字進行排序
sort -r #逆向排序
sort -M #按月份排序
sort -C #檢查是否排序
sort -b #忽略空白
#依據(jù)鍵或列進行排序
sort -k 2 data.txt #依據(jù)第二列來排序
#uniq要么使用管道冬筒,要么使用排過序的文件作文輸入
uniq -u sorted.txt #只顯示唯一的行(即沒有重復(fù)出現(xiàn)的行)
uniq -d sorted.txt #只顯示重復(fù)的行
uniq -s 2 -w 2 sorted.txt #-s忽略前2個字符恐锣,-w指定用于比較的最大字符數(shù)
臨時文件命名、隨機數(shù)
#在編寫shell腳本時舞痰,我們經(jīng)常需要存儲臨時文件土榴。最適合存儲臨時數(shù)據(jù)的位置是 /tmp
#/tmp目錄中的內(nèi)容會在系統(tǒng)重啟后被清空
filename=$RANDOM #RANDOM返回一個隨機數(shù)
filename2=$$ #當(dāng)前shell的PID
filename3=$((date +%F)) #通過日期命令
分割文件和數(shù)據(jù)
#某些情況下,需要把文件分割成多個更小的片段
dd if=/dev/zero bs=100k count=1 of=./data.file #生成一個大小100k內(nèi)容全是0的文件
split -b 20k data.file #-d指定分割大小
#data.file xaa xab xac xad xae,這五個文件都為20k
#我測試了一下响牛,幾個文件加起來數(shù)據(jù)沒變玷禽,幾個文件總行數(shù)沒變
#單位有 k, m, G, c(byte), w(word)
#-d以數(shù)字為后綴, -a指定后綴長度
split data.file -b 20k -d -a 2 spt #增加前綴名'spt'
#data.file spt00 spt01 spt02 spt03 spt04
split -l 10 data.file #-l按行數(shù)來分割文件
#split只能根據(jù)大小或行數(shù)分割文件
#csplit可以根據(jù)文件本身特點進行分割
-f #指定分割后文件前綴
-n #指定分割后文件后綴數(shù)字個數(shù)
-b #指定后綴格式
根據(jù)擴展名切分文件名
#借助%操作符將名稱從 “名稱.擴展名” 格式中提取出來
file="zhang.txt"
name1=${file%.*} #刪除位于%右側(cè)的通配符(.*)所匹配的字符串呀打,通配符從右向左進行匹配
#zhang
#*號通配符矢赁,.號
#%屬于非貪婪匹配(non-greedy),它會匹配通配符最短結(jié)果
#%%屬于貪婪匹配(greedy),它會匹配符號條件的最長字符串
name2=${file#*.} #刪除位于#右側(cè)的通配符(*.)所匹配的字符串贬丛,通配符從左向右進行匹配
#txt
# #屬于非貪婪匹配
# ##屬于貪婪匹配
#栗子
URL=“www.google.com”
echo ${URL%.*} #非貪婪匹配撩银,移除最右邊.及其后面內(nèi)容
www.google
echo ${URL%%.*} #貪婪匹配
www
echo ${URL#*.} #非貪婪匹配,移除最左邊.及其前面內(nèi)容
google.com
echo ${URL##*.} #貪婪匹配
com
批量重命名和移動
#綜合運用find豺憔、rename额获、mv命令
拼寫檢查與詞典操作
#Linux大多數(shù)發(fā)行版都含有一份詞典文件,另外還有一個被稱為aspell的拼寫檢查命令
#words --> /usr/share/dict/linux.words
grep "^good" /usr/share/dict/linux.words
aspell
交互輸入自動化
#寫一個讀取交互式輸入腳本
vi jiaohu.sh
#!/bin/bash
read -p "Input a number:" num
read -p "Input name:" name
echo "You have enterd number:$num, name:$name"
echo -e "1\nzhang" | ./jiaohu.sh
You have entered number:1, name:hello
#or
echo -e "1\nzhang" > input.txt
./jiaohu.sh < input.txt
#交互式輸入自動化
#用expect實現(xiàn)自動化
yum install -y expect
vim auto_expect.sh
#!/bin/expect
spawn ./jiaohu.sh #spawn指定需要自動化哪一個命令
expect "Input a number:" #expect提供需要等待的消息
send "1\n" #send是要發(fā)送的消息
expect "Input name:"
send "zhang"
expect eof #expect eof指明命令交互結(jié)束
./auto_expect.sh