2. 用cat進(jìn)行拼接
cat 用于讀取文件、拼接數(shù)據(jù),還能夠從標(biāo)準(zhǔn)輸入中進(jìn)行讀取。
- 壓縮多余的空白行
cat -s file
壓縮空行.png - 將制表符顯示為^I
cat -T file
制表符顯示.png - 行號(hào)
cat -n file
3. 錄制并回放終端會(huì)話
錄制終端會(huì)話:script -t 2> timing.log -a output.session
結(jié)束錄制:exit
回放:scriptreplay timing.log output.session
(實(shí)測(cè)Ubuntu16.04 效果并不好)
- 若想實(shí)現(xiàn)完整的錄制功能,就必須有一個(gè)
time文件,文件名可以任意取但一定注意-t后面的2>。這條語(yǔ)句是將stderr重定向輸出到文件。缺少這段語(yǔ)句將失去模擬回放的功能。 -
output.file存儲(chǔ)了全部的輸出信息,也是我們回放信息的來源。-a的意義是將輸出append到文件。之所以這么做是因?yàn)樵阡浿破陂g我們已經(jīng)對(duì)命令行作了有效的輸出,所以若要保留這些輸出信息,必須把輸出流復(fù)制一下,也就是append。 - 如果不添加
-a output.file這段語(yǔ)句,則默認(rèn)生成一個(gè)名為typescript的文件,可以使用這個(gè)默認(rèn)文件作為output.file -
output.file中除了輸出的文本信息外,還保存了光標(biāo)移動(dòng)的信息。 - 錄制腳本后用
exit推出 - 如果開始一次新的錄制,應(yīng)該創(chuàng)建兩個(gè)新的記錄文件而非使用原來的。因?yàn)槟_本的
append方式并不會(huì)將原來文件內(nèi)容清空而是在末尾添加。
4. 文件查找與文件列表
- find 命令的工作方式:沿著文件的層次結(jié)構(gòu)向下遍歷,匹配符合條件的文件,執(zhí)行相關(guān)的操作。
-
find base_path從該位置向下搜索
find . -print-print打印搜索到文件的路徑
-print0指明了使用‘\0’作為匹配間的定界符,文件名包含換行符時(shí),使用 - 根據(jù)文件名或正則表達(dá)式進(jìn)行搜索
find /home/slynux -name "*.txt" -print-name 匹配時(shí)忽略大小寫
匹配多個(gè)條件中的一個(gè),可以采用 OR 條件操作:
find . \( -name "*.txt" -o -name ".pdf" \) -print - 否定參數(shù)
find . ! -name "*.txt" -print
否定參數(shù).png - 基于目錄深度的搜索
-maxdepth: 向下遍歷的目錄最大深度
-mindepth:向下遍歷的目錄最小深度
find . -maxdepth 1 -name "f*" -print - 根據(jù)文件類型搜索
-type: 對(duì)文件類型進(jìn)行過濾
如:find . -type d -print
| 文件類型 | 類型參數(shù) |
|---|---|
| 普通文件 | f |
| 符號(hào)鏈接 | l |
| 目錄 | d |
| 字符設(shè)備 | c |
| 塊設(shè)備 | b |
| 套接字 | s |
| FIFO | p |
- 根據(jù)文件時(shí)間進(jìn)行搜索
Linux三種時(shí)間戳:
訪問時(shí)間 -atime:用戶最近一次訪問文件的時(shí)間
修改時(shí)間 -mtime: 文件內(nèi)容最后一次被修改的時(shí)間
變化時(shí)間 -ctime: 文件元數(shù)據(jù)(例如權(quán)限或所有權(quán))最后一次改變的時(shí)間- 打印出最近7天內(nèi)被訪問過的所有文件:
find . -type f -atime -7 -print - 打印出7天前訪問的所有文件
find . -type f -atime 7 -print - 打印出訪問時(shí)間超過7天的所有文件
find . -type f -atime +7 -print
- 打印出最近7天內(nèi)被訪問過的所有文件:
基于時(shí)間的參數(shù)的計(jì)量單位:
-amin 訪問時(shí)間
-mmin 修改時(shí)間
-cmin 變化時(shí)間
打印出時(shí)間超過7分鐘的所有文件
find . -type f -amin +7 -print
-newer 指定一個(gè)比較時(shí)間戳的參考文件,然后找出比參考文件更新的所有文件。
比f(wàn)ile.txt修改時(shí)間更近的所有文件:
find . -type f -newer file.txt -print
- 基于文件大小的檢索
# 大于2KB的文件
find . -type f -size +2k
# 小于2KB的文件
find . -type f -size -2k
| 符號(hào) | 文件大小 |
|---|---|
| b | 塊 512字節(jié) |
| c | 字節(jié) |
| w | 字 2字節(jié) |
| k | 1024字節(jié) |
| M | 1024k 字節(jié) |
| G | 1024M 字節(jié) |
- 刪除匹配的文件
-delete:可以用來刪除find查找到的匹配文件
如:find . -type f -name "*.swap" -delete - 基于文件權(quán)限和所有權(quán)的匹配
-perm:指明find應(yīng)該只匹配基于特殊權(quán)限
如:find . -type f -perm 644 -print
-user: 查找某個(gè)特定用戶所擁有的文件
如:find . -type f -user slynux -print - 利用find執(zhí)行命令或動(dòng)作
#找出root擁有的所有文件,然后用-exec更改所有權(quán)
find . -type f -user root -exec chown slynux {} \;
# {} 對(duì)于任何匹配的文件名,{}均會(huì)被該文件名替換
- 讓find跳過特定的目錄
find devel/source_path \( -name ".git" -prune \) -o \( -type f -print \)
# \( -name ".git" -prune \)的作用就是用來排除
5. 玩轉(zhuǎn) xargs
xargs擅長(zhǎng)將標(biāo)準(zhǔn)輸入數(shù)據(jù)轉(zhuǎn)換為命令行參數(shù)。也可以將單行或多行文本輸入轉(zhuǎn)換為其他格式,例如單行變多行或是多行變單行
-
將stdin接收到的數(shù)據(jù)重新格式化,再將參數(shù)提供給其他命令
將多行轉(zhuǎn)換為單行輸入
將單行轉(zhuǎn)換為多行輸入image.png 用 -d 選項(xiàng)為輸入指定一個(gè)定制的定界符

- 讀取stdin,將格式化參數(shù)傳遞給命令
# 傳遞一個(gè)參數(shù)
./cecho.sh arg1
# 傳遞多個(gè)參數(shù)
./cecho.sh arg1 arg2 arg3
使用xargs

-I 指定替換字符串,在執(zhí)行的時(shí)候進(jìn)行替換
haifei@haifei-ThinkPad-S2-2nd-Gen:~/fileworkspace/linuxshell/S02$ cat args.txt | xargs -I {} ./s01_cecho.sh -p {} -l
-p arg1 -l#
-p arg2 -l#
-p arg3 -l#
- 結(jié)合find使用xargs
# xargs與find是一對(duì)死黨。注意find后的定界符,下面是刪除.txt文件
# -print0 指明 \0 為定界符,-0 是以\0為定界符
find . -type f -name "*.txt" -print0 | xargs -0 rm -f
# 統(tǒng)計(jì)C程序文件的行數(shù)
find source_code_dir_path -type f -name "*.c" -print0 | xargs -0 wc -l
6. 用tr進(jìn)行轉(zhuǎn)換
tr是對(duì)來自標(biāo)準(zhǔn)輸入的內(nèi)容進(jìn)行字符替換,字符刪除和重復(fù)字符壓縮等操作。使用格式如下:
tr [options] set1 set2
由set1映射到set2,然后將輸出寫入stdout。如果兩個(gè)字符集的長(zhǎng)度不相等,set2會(huì)不斷重復(fù)最后一個(gè)字符。set2大于set1,超出被忽略
#用tr刪除字符
$ echo "Hello 123 world 456" | tr -d '0-9'
Hello world
# 字符串補(bǔ)集, -c 為取反
$ echo "Hello 1 char 2 next 4" | tr -d -c '0-9 \n'
1 2 4
# 用tr壓縮字符
$ echo "GNU is not UNIX. Recursive right ?" | tr -s ' '
GNU is not UNIX. Recursive right ?
tr可以使用集合一樣使用不同的字符類,這些字符類包括:
使用方式
tr [:class:] [:class:]
如:tr '[:lower:]' '[:upper:]'
| 字符類 | 說明 |
|---|---|
| alnum | 字母和數(shù)字 |
| alpha | 字母 |
| cntrl | 控制字符 |
| digit | 數(shù)字 |
| graph | 圖形字符 |
| lower | 小寫字母 |
| 可打印字符 | |
| punct | 標(biāo)點(diǎn)符號(hào) |
| space | 空白字符 |
| upper | 大寫字母 |
| xdigit | 十六進(jìn)制字符 |
7. 校驗(yàn)和與核實(shí)
檢驗(yàn)和程序用于生成 校驗(yàn)和秘鑰,然后利用這個(gè)校驗(yàn)和秘鑰核實(shí)文件的完成性。
用于文件完整性測(cè)試的特定秘鑰稱為校驗(yàn)和
# 計(jì)算md5sum,會(huì)生成
$ md5sum args.txt
3f228b61493cf779a95c94dd8e11328b args.txt
#將md5sum重定向到一個(gè)文件,使用MD5文件核實(shí)數(shù)據(jù)完整性
md5sum filename > file_sum.md5
#校驗(yàn)
md5sum -c file_sum.md5
# 檢查所有的文件
md5sum -c *.md5
#SHA-1與上類似,md5sum替換為sha1sum,生成的文件為.sha1
#對(duì)目錄進(jìn)行檢驗(yàn)
md5deep -rl directory_path > directory.md5
#使用find來遞歸計(jì)算校驗(yàn)和:
find directory_path -type f -print0 | xargs -0 md5sum >> directory.md5
#核實(shí)
md5sum -c directory.md5
8. 加密工具與散列
加密技術(shù)主要用于數(shù)據(jù)遭受未經(jīng)授權(quán)的訪問。
crypt gpg base64 md5sum sha1sum openssl
# crypt是簡(jiǎn)單的加密工具,它從stdin接受一個(gè)文件以及口令作為輸入,然后將加密數(shù)據(jù)輸入到Stdout
$ crypt <input_file >output_file
Enter passphrase:
#通過命令行參數(shù)來提供口令
crypt PASSPHEASE <input_file >output_file
# 解密文件
crypt PASSPHEASE -d <encrypted_file >output_file
# gpg 使用加密技術(shù)保護(hù)文件,確保數(shù)據(jù)在送達(dá)目的地之前無法被讀取
#加密,會(huì)生成filename.gpg
gpg -c filename
#讀取口令,然后對(duì)文件進(jìn)行解密
gpg filename.gpg
#base64 是一組相似的編碼方案,他將ASCII字符轉(zhuǎn)換為以64為基數(shù)的形式,以可讀的ASCII字符串來描述二進(jìn)制文件。
# 加密
base64 filename > outputfile
cat file | base64 > outputfile
#解碼
base64 -d file > outputfile
cat base64_file | base64 -d > outputfile
# md5sum 與 sha1sum 都是單向散列算法,無法逆向出原始數(shù)據(jù),常用于驗(yàn)證數(shù)據(jù)完整性或?yàn)樘囟〝?shù)據(jù)生成唯一的秘鑰。
md5sum file
sha1sum file
# shadow-like散列(salt散列)
#SALT指額外的字符串,用來起一個(gè)混淆的作用,使加密不易破解。
opensslpasswd -l -salt SALT_STRING PASSWORD
將SALT_STRING替換為隨機(jī)字符串,并將PASSWORD替換為你想要的密碼
9. 排序、唯一與重復(fù)
# 簡(jiǎn)單排序
sort file1.txt file2.txt > sorted.txt
sort file1.txt file2.txt -o sorted.txt
# 數(shù)字順序排序
sort -n file.txt
# 逆序進(jìn)行排序
sort -r file.txt
# 月份進(jìn)行排序
sort -M months.txt
# 合并倆個(gè)已排序過的文件
sort -m sorted1 sorted2
# 找出文件是否已經(jīng)排序過
sort file1.txt file2.txt | uniq
# 檢查文件是否排序過
#!/bin/bash
sort -C filename ;
if [ $? -eq 0 ]; then
echo Sorted;
else
echo Unsorted;
fi
1.依據(jù)鍵或列進(jìn)行排序
$ cat data.txt
1 mac 2000
2 winxp 4000
3 bsd 1000
4 linux 1000
# -k指定了排序應(yīng)該按照哪一個(gè)鍵進(jìn)行,-r 告訴sort命令按照逆序排序
$ sort -nrk 1 data.txt
4 linux 1000
3 bsd 1000
2 winxp 4000
1 mac 2000
$ sort -k 2 data.txt
3 bsd 1000
4 linux 1000
1 mac 2000
2 winxp 4000
# uniq命令通過消除重復(fù)內(nèi)容,從給定輸入中找出唯一的行。他也可以用來消除重復(fù)行
$cat sorted.txt
bash
foss
hack
hack
# 重復(fù)的行只打印一次
$ uniq sorted.txt
bash
foss
hack
# 重復(fù)行不打印
$ uniq -u sorted.txt
$ sort sorted.txt | uniq -u
# 統(tǒng)計(jì)各行在文件中出現(xiàn)的次數(shù)
$ sort sorted.txt | uniq -c
# 找出文件中重復(fù)的行
$ sort sorted.txt | uniq -d
# -s 指定可以跳過前 n 個(gè)字符
# -w 指定用于比較的最大字符數(shù)
$ cat data3.txt
u:01:gnu
d:04:linux
u:01:bash
u:01:back
$ sort data3.txt | uniq -s 2 -w 2
d:04:linux
u:01:back
10. 臨時(shí)文件命名與隨機(jī)數(shù)
最適合存儲(chǔ)臨時(shí)數(shù)據(jù)的位置是/tmp
# 創(chuàng)建臨時(shí)文件:
$ filename=`mktemp`
$ echo $filename
/tmp/tmp.azrfACVCNy
# 創(chuàng)建臨時(shí)目錄
$ dirname=`mktemp -d`
$ echo $dirname
/tmp/tmp.2P3ESjrx1y
# 生成文件名,有不希望生成實(shí)際的文件或目錄
$ tempfile=`mktemp -u`
$ echo $tempfile
/tmp/tmp.RXlgIJpWMw
# 根據(jù)模板生成臨時(shí)文件
$ mktemp test.XXX
test.Cmy
11. 分割文件和數(shù)據(jù)
# 將文件分割為多個(gè)大小為1k的文件, -b指定分割大小
$ split -b 1k wifi_password.odt
$ ls
wifi_password.odt xaa xab xac xad xae xaf xag xah xai
# -d指定使用數(shù)字后綴,-a length 指定后綴長(zhǎng)度
$ ls
wifi_password.odt x0000 x0001 x0002 x0003 x0004 x0005 x0006 x0007 x0008
# 分割后文件設(shè)置前綴
$ split -b 1k wifi_password.odt -d -a 4 split_file
$ ls
split_file0000 split_file0001 split_file0002 split_file0003 split_file0004 split_file0005 split_file0006 split_file0007 split_file0008 wifi_password.odt
# 根據(jù)行數(shù)分割文件
$ split -l 10 data.file
12. 根據(jù)擴(kuò)展名切分文件名
# #代表了由左向右最小匹配,%代表了右向左最小匹配
# ##由左向右最大 匹配,%%代表了右向左最小匹配
# 移除 .* 匹配的最右邊的內(nèi)容,假設(shè)URL=WWW.google.com
$ echo ${URL%.*}
WWW.google
# 右邊開始一直匹配到的 *. 移除
$ echo ${URL%%.*}
WWW
# 移除 *. 所匹配的最左邊的內(nèi)容
$ echo ${URL#*.}
google.com
#
$ echo ${URL##*.}
com
13. 批量重命名和移動(dòng)
# 將 *JPG 更名為 *.jpg
$ rename *.JPG *.jpg
# 替換文件名中的空格替換為字符“_”
$ rename 's/ /_/g'
# 轉(zhuǎn)換文件名大小寫
$ rename 'y/A-Z/a-z/' *
# 移動(dòng).mp3 到指定目錄
$ find path -type f -name "*.mp3" -exec mv {} target_dir \;
# 將所有文件名中的空格替換為字符“_”
$ find path -type f -exec rename 's/ /_/g' {} \;
14. 拼寫檢查與詞典操作
# 包含的詞典文件
$ ls /usr/share/dict/
american-english british-english
# 檢查給定的單詞是否為詞典中的單詞
# ^ 單詞的開始, $ 單詞的結(jié)束 -q 禁止產(chǎn)生任何輸出
grep “^word$” /usr/share/dict/british-english -q #(這個(gè)要看返回值)
# 列出文件中以特定單詞起頭的所有單詞
$ look word filepath
$ grep "^word" filepath
# 如果沒有給出文件參數(shù),默認(rèn)使用/usr/share/dict/words
15. 交互輸入自動(dòng)化
$ cat S02_15_interactive.sh
#!/bin/bash
read -p "Enter number:" no ;
read -p "Enter name:" name ;
echo your have enter $no, $name;
$ sh S02_15_interactive.sh
Enter number:200
Enter name:haifei
your have enter 200, haifei
# -e表示生成輸入序列,會(huì)解釋其中的\n分界符
$ echo -e "200\nhello\n" | ./S02_15_interactive.sh
your have enter 200, hello
# expect等待特定的輸入提示,通過檢查輸入提示來發(fā)送數(shù)據(jù)
$ cat s02_15_automate_expect.sh
#!/bin/bash
spawn ./interactive.sh
expect "Enter number:"
send "1\n"
expect "Enter name:"
send "hello\n"
expect eof
# spawn參數(shù)指定需要自動(dòng)化哪一個(gè)命令
# expect 參數(shù)提供需要等待的消息
# send 是要發(fā)送的消息
# expect eof 指明命令交互結(jié)束
16. 利用并行進(jìn)程速命令執(zhí)行
$字符將使得shell命令置于后臺(tái)并繼續(xù)執(zhí)行腳本
$!保存著最近一個(gè)后臺(tái)進(jìn)程的PID,我們將這些PID放入數(shù)組,使用wait命令等待這些進(jìn)程結(jié)束



