1.用cat進行拼接
- 打印文件內容
cat file1 file2 ...
- 將文件內容和stdin拼接在一起
[work@jkz ~]$ echo 'Text through stdin' | cat text
1
2
3
[work@jkz ~]$ echo 'Text through stdin' | cat - text
Text through stdin
1
2
3
- 去掉多余的空白行
[work@jkz ~]$ cat text
1
2
3
[work@jkz ~]$ cat -s text
1
2
3
- 將制表符顯示為^I
[work@jkz ~]$ cat file.py
def function():
var = 5
next = 6
third=7
[work@jkz ~]$ cat -T file.py
def function():
^Ivar = 5
^I^Inext = 6
^Ithird=7
- 行號
[work@jkz ~]$ cat -n text
1 1
2
3
4 2
5
6 3
- 利用管道重定向輸出會清空輸入文件
[work@jkz ~]$ cat text | cat -n > text
[work@jkz ~]$ cat text
[work@jkz ~]$
2.錄制并回放終端會話
script命令能夠錄制你的擊鍵以及擊鍵時機,并將輸入和輸出結果保存在對應的文件中。scriptreplay命令可以回放會話。
[work@jkz ~]$ script -t 2> timing.log -a out.session
Script started, file is out.session
[work@jkz ~]$ tclsh
% puts [expr 2 + 2]
4
% exit
[work@jkz ~]$ exit
exit
Script done, file is out.session
[work@jkz ~]$ scriptreplay timing.log out.session
[work@jkz ~]$ tclsh
% puts [expr 2 + 2]
4
% exit
[work@jkz ~]$ exit
3.查找并列出文件
find命令的工作方式如下:沿著文件層次結構向下遍歷,匹配符合條件的文件,執行相應的操作。默認的操作是打印出文件和目錄,這也可以使用-print選項來指定。
find命令能夠基于通配符或正則表達式、目錄樹深度、文件日期、文件類型等條件查找文件。
- 列出指定目錄
find path
- -print0
print選項使用\n(換行符)分隔輸出的每個文件或目錄名。而-print0選項則使用空字符'\0'來分隔。-print0的主要用法是將包含換行符或空白字符的文件名傳給xargs命令。
[work@jkz shelldir]$ echo "test" > "file name"
[work@jkz shelldir]$ ls
file name
[work@jkz shelldir]$ find . -type f -print | xargs ls -l
ls: cannot access ./file: No such file or directory
ls: cannot access name: No such file or directory
[work@jkz shelldir]$ find . -type f -print0 | xargs -0 ls -l
-rw-rw-r-- 1 work work 5 Dec 13 07:43 ./file name
- 根據文件名或正則表達式進行搜索
-name選項指定了待查找文件名的模式。這個模式可以是通配符,也可以是正則表達式。
-iname(忽略字母大小寫)。
find命令支持邏輯操作符。-a和-and選項可以執行邏輯與(AND)操作,-o和-or選項可以執行邏輯或(OR)操作。
-path選項可以限制所匹配文件的路徑及名稱。
-regex選項和-path類似,只不過前者是基于正則表達式來匹配文件路徑的。-iregex忽略大小寫。
find . \( -name '*.sh' -o -name '*.log' \)
[work@jkz ~]$ find . -path '*/shell*/*' -name '*.txt'
./shelldir/hello.txt
find . -regex '.*\(\.sh\|\.log\)$'
注意*.txt兩邊的單引號。shell會擴展沒有引號或是出現在雙引號(")中的通配符。單引號能夠阻止shell擴展*.txt,使得該字符串能夠原封不動地傳給find命令。
否定參數
find . ! -path '*apache*'
基于目錄深度的搜索
默認情況下,find命令不會跟隨符號鏈接。-L選項可以強制其改變這種行為。但如果碰上了指向自身的鏈接,find命令就會陷入死循環中。
-maxdepth和–mindepth選項可以限制find命令遍歷的目錄深度。
-maxdepth和-mindepth應該在find命令中及早出現。如果作為靠后的選項,有可能會影響到find的效率,因為它不得不進行一些不必要的檢查。-
根據文件類型搜索
find命令可以使用-type選項對文件類型進行過濾。
根據文件的時間戳進行搜索
訪問時間(-atime):用戶最近一次訪問文件的時間。
修改時間(-mtime):文件內容最后一次被修改的時間。
變化時間(-ctime):文件元數據(例如權限或所有權)最后一次改變的時間。
打印出在最近7天內被訪問過的所有文件:
find . -type f -atime -7
打印出恰好在7天前被訪問過的所有文件:
find . -type f -atime 7
打印出訪問時間超過7天的所有文件:
find . -type f -atime +7
find命令還支持以“分鐘”為計時單位的選項:
-amin/-mmin/-cmin
–newer選項可以指定一個用于比較修改時間的參考文件,然后找出比參考文件更新的(更近的修改時間)所有文件。
找出比file.txt修改時間更近的所有文件:
find . -type f -newer file.txt
基于文件大小的搜索
大于2KB的文件:
find . -type f -size +2k
小于2KB的文件:
find . -type f -size -2k
大小等于2KB的文件:
find . -type f -size 2k
其他文件大小單位:
b:塊(512字節)。
c:字節。
w:字(2字節)。
k:千字節(1024字節)。
M:兆字節(1024K字節)。
G:吉字節(1024M字節)。基于文件權限和所有權的匹配
-perm選項指明find應該只匹配具有特定權限值的文件。
打印出權限為644的文件:
find . -type f -perm 644
也可以根據文件的所有權進行搜索。用選項 -user USER就能夠找出由某個特定用戶所擁有的文件。
find . -type f -user root利用find執行相應操作
find命令能夠對其所查找到的文件執行相應的操作。
刪除匹配的文件,find命令的-delete選項可以刪除所匹配到的文件。
從當前目錄中刪除.swp文件:
find . -type f -name "*.swp" -delete
利用-exec選項,find命令可以結合其他命令使用。find命令使用一對花括號{}代表文件名。對于每一個匹配的文件,find命令會將{}替換成相應的文件名并更改該文件的所有權。
find . -type f -user root -exec chown work {} ;
注意該命令結尾的;。必須對分號進行轉義,否則shell會將其視為find命令的結束,而非chown命令的結束。
為每個匹配到的文件調用命令可是個不小的開銷。如果指定的命令接受多個參數(如chown),你可以換用加號(+)作為命令的結尾。這樣find會生成一份包含所有搜索結果的列表,然后將其作為指定命令的參數,一次性執行。
將給定目錄中的所有C程序文件拼接起來寫入單個文件all_c_files.txt:
$ find . -type f -name '*.c' -exec cat {} ;>all_c_files.txt
$ find . -type f -name '*.c' -exec cat {} > all_c_files.txt ;
$ fine . -type f -name '*.c' -exec cat {} >all_c_files.txt +
沒有使用>>(追加)的原因是find命令的全部輸出就只有一個數據流(stdin)
將10天前的 .txt文件復制到OLD目錄中:
find . -type f -mtime +10 -name "*.txt" -exec cp {} OLD ;
-exec選項只能夠接受單個命令。不過可以把多個命令寫到一個shell 腳本中( 例如command.sh),然后在-exec中使用這個腳本:
-exec ./commands.sh {} ;
- 讓find跳過特定的目錄
在搜索時排除某些文件或目錄的技巧叫作修剪。使用-prune選項排除某些符合條件的文件。
跳過apache-tomcat-8.5.35目錄:
find ./ -name 'apache-tomcat-8.5.35' -prune -o -type f
4.玩轉xargs
調用只能接受命令行參數命令的方法:
- 利用管道
- 使用反引號執行命令,然后將其輸出作為命令行參數
如果處理文件過多,會報錯。
gcc `find '*.c'`
- 使用xargs命令。(xargs命令可以解決反引號的問題)
xargs命令應該緊跟在管道操作符之后。它使用標準輸入作為主要的數據源,將從stdin中讀取的數據作為指定命令的參數并執行該命令。
在一組sh中搜索字符串bash
ls *.sh | xargs grep bashxargs命令重新格式化stdin接收到的數據,再將其作為參數提供給指定命令。xargs默認會執行echo命令。和find命令的-exec選項相比,兩者在很多方面都相似。
將多行輸入轉換成單行輸出。
cat test | xargs將單行輸入轉換成多行輸出。xargs的-n選項可以限制每次調用命令時用到的參數個數。下面的命令將輸入分割成多行,每行n個元素:
[work@jkz ~]$ cat text | xargs -n 3
1 2 3
4 5 6
7 8 9
10 11 12
[work@jkz ~]$ cat text | xargs -n 4
1 2 3 4
5 6 7 8
9 10 11 12
工作原理
xargs命令接受來自stdin的輸入,將數據解析成單個元素,然后調用指定命令并將這些元素作為該命令的參數。xargs默認使用空白字符分割輸入并執行/bin/echo。
- 如果文件或目錄名中包含空格(甚至是換行)的話,使用空白字符來分割輸入就會出現問題。
但是可以定義一個用來分隔參數的分隔符。-d選項可以為輸入數據指定自定義的分隔符
[work@jkz ~]$ echo "splitXsplit2Xsplit3Xsplit4" | xargs -d X
split split2 split3 split4
- xargs命令可以同find命令很好地結合在一起。find的輸出可以通過管道傳給xargs,由后者執行-exec選項所無法處理的復雜操作。如果文件系統的有些文件名中包含空格,find命令的-print0選項可以使用0(NULL)來分隔查找到的元素,然后再用xargs對應的-0選項進行解析。下面的例子在Samba掛載的文件系統中搜索.docx文件,這些文件名中通常會包含大寫字母和空格。其中使用了grep找出內容中不包含image的文件:
find /smbMount -iname '*.docx' -print0 | xargs -0 grep -L image
解釋:使用0以后,對于找到的文件名含有空格的元素,會被當做一個整體傳給xargs。xargs同理是以0作為分隔符,所以不會出現誤操作。其實這本是上也是協議,find作為發送端,xargs作為接收端。雙方要協商好處理的協議。
默認情況下,由xargs添加的參數都被放置在指定命令的尾部。
cat args.txt | xargs -n 2 ./cecho.shxargs有一個選項-I,可以用于指定替換字符串,這個字符串會在xargs解析輸入時被參數替換掉。如果將-I與xargs結合使用,對于每一個參數,指定命令只會執行一次。-I {}指定了替換字符串,命令以循環的方式執行。為該命令提供的各個參數會通過stdin讀取并依次替換掉字符串{}。
[work@jkz ~]$ cat args.txt | xargs -I {} ./cecho.sh -p {} -l
-p arg1 -l#
-p arg2 -l#
-p arg3 -l#
xargs和find可以配合完成任務。不過在結合使用的時候需要留心。
find . -type f -name "*.txt" -print | xargs rm -f
這樣做很危險,有可能會誤刪文件。我們無法預測find命令輸出的分隔符究竟是什么(究竟是'\n'還是' ')。如果有文件名中包含空格符(' '),xargs會將其誤認為是分隔符。
更安全的做法:使用find命令的-print0選項生成以空字符('\0')作為分隔符的輸出,然后將其作為xargs命令的輸入。
find . -type f -name "*.txt" -print0 | xargs -0 rm -f統計源代碼目錄中所有C程序文件的行數
find source_code_dir_path -type f -name "*.c" -print0 | xargs -0 wc –l結合stdin,巧妙運用while語句和子shell
xargs會將參數放置在指定命令的尾部,因此無法為多組命令提供參數。可以通過創建子shell來處理這種復雜情況。
$ cat files.txt | ( while read arg; do cat $arg; done )
# 等同于cat files.txt | xargs -I {} cat {}
在while循環中,可以將cat $arg替換成任意數量的命令,這樣我們就可以對同一個參數執行多條命令。也可以不借助管道將輸出傳遞給其他命令。這種利用()創建子shell的技巧可以應用于各種問題場景。
shell的-c選項可以調用子shell來執行命令行腳本。它可以與xargs結合解決多次替換的問題。下列命令找出了所有的shell文件并顯示出每個文件的名字,文件名前會加上一個換行符(-e選
項允許進行轉義替換)。在文件名之后是該文件中含有bash的所有行:
find . -name '*.sh' | xargs -I ^ sh -c "echo -ne ' ^: '; grep bash ^"
5.用tr進行轉換
tr可用于編寫優雅的單行命令。tr可以對來自標準輸入的內容進行字符替換、字符刪除以及重復字符壓縮。tr是translate(轉換)的簡寫,因為它可以將一組字符轉換成另一組字符。
tr只能通過stdin(標準輸入)接收輸入(無法通過命令行參數接收)。
調用格式:
tr [options] set1 set2
來自stdin的輸入字符會按照位置從set1映射到set2(set1中的第一個字符映射到set2中的第一個字符,以此類推),然后將輸出寫入stdout(標準輸出)。如果兩個字符組的長度不相等,那么set2會不斷復制其最后一個字符,直到長度與set1相同。如果set2的長度大于set1,那么在set2中超出set1長度的那部分字符則全部被忽略。
[work@jkz ~]$ echo "HELLO WORLD" | tr 'A-Z' 'a-z'
hello world
'ABD-}'、'aA.,'、'a-ce-x'以及'a-c0-9'等均是合法的集合。使用“起始字符-終止字符”這種格式。這種寫法也可以和其他字符或字符類結合使用。如果“起始字符-終止字符”不是有效的連續字符序列,那么它就會被視為含有3個元素的集合(起始字符、-和終止字符)。也可以使用像'\t'、'\n'這種特殊字符或其他ASCII字符。
將制表符轉換成單個空格:
tr '\t' ' ' < file.txt
- 刪除字符
選項-d,可以通過指定需要被刪除的字符集合,將出現在stdin中的特定字符清除掉:
[work@jkz ~]$ echo "hello 123 world 356" | tr -d '0-9'
hello world
- 字符組補集
利用選項-c來使用set1的補集。
只給出了set1,那么tr會刪除所有不在set1中的字符。
[work@jkz ~]$ echo "hello 1 char 2 next 4" | tr -d -c '0-9 \n'
1 2 4
也給出了set2,tr會將不在set1中的字符轉換成set2中的字符。
[work@jkz ~]$ echo "hello 1 char 2 next 4" | tr -c '0-9' '-'
------1------2------4-
- 壓縮字符
可以刪除字符串中重復出現的字符。
tr -s '[需要被壓縮的一組字符]'
[work@jkz ~]$ echo "GNU is not UNIX. Recursive right ?" | tr -s ' '
GNU is not UNIX. Recursive right ?
用tr以一種巧妙的方式將文件中的數字列表進行相加
[work@jkz ~]$ cat sum.txt
1
2
3
4
5
[work@jkz ~]$ cat sum.txt | echo $[$(tr '\n' '+') 0]
15
tr命令將'\n'替換成了'+',我們因此得到了字符串1+2+3+..5+,但是在字符串的尾部多了一個操作符+。為了抵消這個多出來的操作符,我們再追加一個0。
$[ operation ]執行算術運算。
- 字符類
alnum:字母和數字。
alpha:字母。
cntrl:控制(非打印)字符。
digit:數字。
graph:圖形字符。
lower:小寫字母。
print:可打印字符。
punct:標點符號。
space:空白字符。
upper:大寫字母。
xdigit:十六進制字符。
示例:
tr '[:lower:]' '[:upper:]'
6.校驗和與核實
校驗和能夠讓我們核實文件中所包含的數據是否和預期的一樣。
強健性最好且使用最為廣泛的校驗和算法是MD5和SHA-1。
md5sum是一個長度為32個字符的十六進制串。
[work@jkz ~]$ md5sum text > text.md5
[work@jkz ~]$ md5sum -c text.md5
text: OK
[work@jkz ~]$ vim text
[work@jkz ~]$ md5sum -c text.md5
text: FAILED
md5sum: WARNING: 1 computed checksum did NOT match
[work@jkz ~]$ cat text.md5
714a63efb5a21cd8786c59e3ec1f892f text
SHA-1是另一種常用的校驗和算法。它從給定的輸入中生成一個長度為40個字符的十六進制串。用來計算SAH-1校驗和的命令是sha1sum,其用法和md5sum的類似。只需要把先前講過的那些命令中的md5sum改成sha1sum就行了,記住將輸出文件名從file_sum.md5改為file_sum.sha1。
[work@jkz ~]$ sha1sum text > text.sha1
[work@jkz ~]$ cat text.sha1
700634a38bdc7b886fc43e6956a1b344083c99eb text
[work@jkz ~]$ sha1sum -c text.sha1
text: OK
[work@jkz ~]$ vim text
[work@jkz ~]$ sha1sum -c text.sha1
text: FAILED
sha1sum: WARNING: 1 computed checksum did NOT match
對目錄進行校驗
md5deep或sha1deep命令可以遍歷目錄樹,計算其中所有文件的校驗和。md5與SHA-1都是單向散列算法,均無法逆推出原始數據。這種類型的散列算法多用于存儲密碼。密碼只存儲其對應散列值。如果需要認證某個用戶,則讀取該用戶提供的密碼并轉換成散列值,然后與之前存儲的散列值進行比對。如果相同,用戶則通過認證并授權訪問。
盡管應用廣泛,md5sum和SHA-1已不再安全,因為近年來計算能力的攀升使其變得容易被破解。推薦使用bcrypt或sha512sum這類工具進行加密。更多信息可參看https://codahale.com/how-to-safely-store-a-password/。
shadow-like散列(加鹽散列)
shadow密碼通常都是加鹽密碼(salted password)。所謂的“鹽”(SALT)就是一個額外的字符串,起混淆的作用,使加密更加難以破解。鹽是由一些隨機位組成的,它們作為密鑰生成函數的輸入之一,產生密碼的加鹽散列。
https://en.wikipedia.org/wiki/Salt_(cryptography)
7.加密工具與散列
加密技術主要用于防止數據遭受未經授權的訪問。和上面講的校驗和算法不同,加密算法可以無損地重構原始數據。
crypt命令通常并沒有安裝在Linux系統中。它是一個簡單的加密工具,相對而言不是那么安全。該命令從stdin接受輸入,要求用戶創建口令,然后將加密數據輸出到 stdout.
gpg(GNU privacy guard,GNU隱私保護)是一種應用廣泛的工具,它使用加密技術來保護文件,以確保數據在送達目的地之前無法被讀取。
Base64是一組相似的編碼方案,它將二進制數據轉換成以64為基數的形式(radix-64 representation),以可讀的ASCII字符串進行描述。
8.行排序
sort命令能夠對文本文件和stdin進行排序。它可以配合其他命令來生成所需要的輸出。uniq經常與sort一同使用,提取不重復(或重復)的行。
sort file1.txt file2.txt > sorted.txt
sort file1.txt file2.txt -o sorted.txt
按照數字順序:
sort -n file.txt
逆序:
sort -r file.txt
按照月份排序:
sort -M months.txt
合并兩個已排序過的文件:
sort -m sorted1 sorted2
找出已排序文件中不重復的行,uniq要求數據必須經過排序:
sort file1.txt file2.txt | uniq
檢查文件是否已經排序過:
sort -c filename
echo $?
根據哪一列進行排序,通過-k指定,列與列之間由空格分隔。:
sort -k 2 data.txt
終止符\0用來確保安全地使用xargs命令:
sort -z data.txt | xargs -0
選項-b用于忽略文件中的前導空白行,選項-d用于指明以字典序進行排序:
sort -bd unsorted.txt
uniq命令可以從給定輸入中(stdin或命令行參數指定的文件)找出唯一的行,報告或刪除那些重復的行。
uniq只能作用于排過序的數據,因此,uniq通常都與sort命令結合使用。
統計各行在文件中出現的次數:
sort unsorted.txt | uniq -c
找出文件中重復的行:
sort unsorted.txt | uniq -d
可以結合-s和-w選項來指定鍵,-s 指定跳過前N個字符,-w 指定用于比較的最大字符數
將命令輸出作為xargs命令的輸入時,最好為輸出的各行添加一個0值字節(zero-byte)終止符。因為在默認情況下,xargs命令會用空格來分割參數。
-z選項可以生成由0值字節終止的輸出:
uniq -z file.txt
9.臨時文件命名與隨機數
最適合存儲臨時數據的位置是 /tmp(該目錄中的內容在系統重啟后會被清空)。
臨時文件:
$ filename=`mktemp`
$ echo $filename
/tmp/tmp.8xvhkjF5fH
臨時目錄:
$ dirname=`mktemp -d`
$ echo $dirname
tmp.NI8xzW7VRX
僅僅是想生成文件名,不希望創建實際的文件或目錄:
$ tmpfile=`mktemp -u`
$ echo $tmpfile
/tmp/tmp.RsGmilRpcT
基于模板創建臨時文件名:
$mktemp test.XXX
test.2tc
如果提供了定制模板,X會被隨機的字符(字母或數字)替換。注意,mktemp正常工作的前提是保證模板中至少要有3個X。
10.分割文件與數據
split命令可以用來分割文件。該命令接受文件名作為參數,然后創建出一系列體積更小的文件,其中依據字母序排在首位的那個文件對應于原始文件的第一部分,排在次位的文件對應于原始文件的第二部分,以此類推。
在split命令中,除了k(KB),我們還可以使用M(MB)、G(GB)、c(byte)和w(word):
split -b 10k data.file
split默認使用字母后綴。如果想使用數字后綴,需要使用-d選項。此外, -a length
可以指定后綴長度:
split -b 10k data.file -d -a 4
為分割后的文件指定文件名前綴,可以通過提供一個前綴作為最后一個參數來實現:split -b 10k data.file -d -a 4 split_file
根據行數來分割文件的話,可以使用 -l no_of_lines:
split -l 10 data.file
csplit實用工具能夠基于上下文來分隔文件。它依據的是行計數或正則表達式。這個工具對于日志文件分割尤為有用。
- /SERVER/ 用來匹配特定行,分割過程即從此處開始。
/[REGEX]/ 用于描述文本模式。它從當前行(第一行)一直復制到(但不包括)包含SERVER的匹配行。
{*} 表示根據匹配重復執行分割操作,直到文件末尾為止。可以用{整數}的形式來指定分割執行的次數。
-s 使命令進入靜默模式,不打印其他信息。
-n 指定分割后的文件名后綴的數字個數,例如01、02、03等。
-f 指定分割后的文件名前綴(在上面的例子中,server就是前綴)。
-b 指定后綴格式。例如%02d.log,類似于C語言中printf的參數格式。在這里:文件名 = 前綴 + 后綴,也就是server + %02d.log。
[work@jkz ~]$ cat server.log
SERVER-1
[connection] 192.168.0.1 success
[connection] 192.168.0.2 failed
[disconnect] 192.168.0.3 pending
[connection] 192.168.0.4 success
SERVER-2
[connection] 192.168.0.1 failed
[connection] 192.168.0.2 failed
[disconnect] 192.168.0.3 success
[connection] 192.168.0.4 failed
SERVER-3
[connection] 192.168.0.1 pending
[connection] 192.168.0.2 pending
[disconnect] 192.168.0.3 pending
[connection] 192.168.0.4 failed
[work@jkz ~]$ csplit server.log /SERVER/ -n 2 -s {*} -f server -b "%02d.log"
[work@jkz ~]$ ls |grep server
server00.log
server01.log
server02.log
server03.log
server.log
[work@jkz ~]$ cat server00.log
[work@jkz ~]$ cat server01.log
SERVER-1
[connection] 192.168.0.1 success
[connection] 192.168.0.2 failed
[disconnect] 192.168.0.3 pending
[connection] 192.168.0.4 success
[work@jkz ~]$
11.根據擴展名切分文件名
借助%操作符可以從name.extension這種格式中提取name部分(文件名):
[work@jkz ~]$ file="sample.jpg"
[work@jkz ~]$ name=${file%.*}
[work@jkz ~]$ echo $name
sample
#操作符可以提取出擴展名:
[work@jkz ~]$ extension=${file#*.}
[work@jkz ~]$ echo $extension
jpg
${VAR%.*} 的含義如下:
- 從 $VAR中刪除位于%右側的通配符(在上例中是.*)所匹配的字符串。通配符從右向左進行匹配。
- 給VAR賦值,即VAR=sample.jpg。通配符從右向左匹配到的內容是.jpg,因此從$VAR中刪除匹配結果,得到輸出sample。
%屬于非貪婪(non-greedy)操作。它從右向左找出匹配通配符的最短結果。還有另一個操作符%%,它與%相似,但行為模式卻是貪婪的,這意味著它會匹配符合通配符的最長結果。
[work@jkz ~]$ VAR=hack.fun.book.txt
[work@jkz ~]$ echo ${VAR%.*}
hack.fun.book
[work@jkz ~]$ echo ${VAR%%.*}
hack
#操作符與%類似,不過求值方向是從左向右。
${VAR#*.}的含義如下:
- 從$VAR中刪除位于#右側的通配符(即在上例中使用的*.)從左向右所匹配到的字符串。
#也有一個對應的貪婪操作符##:
[work@jkz ~]$ echo ${VAR#*.}
fun.book.txt
[work@jkz ~]$ echo ${VAR##*.}
txt
12.多個文件的重命名與移動
mv可以進行重命名。
rename命令利用Perl正則表達式修改文件名。組合find、rename和mv命令,我們能做到的事其實很多。
- 將 *.JPG更名為 *.jpg:
rename *.JPG *.jpg - 將文件名中的空格替換成字符 "_":
rename 's/ /_/g' * - 轉換文件名的大小寫:
rename 'y/A-Z/a-z/' *
rename 'y/a-z/A-Z/' * - 將所有的.mp3文件移入給定的目錄:
find path -type f -name "*.mp3" -exec mv {} target_dir ; - 以遞歸的方式將所有文件名中的空格替換為字符"_":
find path -type f -exec rename 's/ /_/g' {} ;
13.拼寫檢查與詞典操作
大多數Linux發行版都含有一份詞典文件。還有一個叫作aspell的命令行實用工具,其作用是進行拼寫檢查。
look命令可以顯示出以特定字符串起始的行。你可以用它在日志文件中查找以特定日期為首的記錄,或是在詞典中查找以特定字符串開頭的單詞。look默認會搜索/usr/share/dict/words,你也可以給出文件供其搜索。
14.交互輸入自動化
可以創建自己的交互式shell腳本。對于普通用戶而言,相較于記憶命令行參數及其正確的順序,同一系列提示信息打交道要更容易。
交互式腳本:
$ backup.sh
What folder should be backed up? notes
What type of files should be backed up? .docx
實現:
#!/bin/bash
# backup.sh
# 使用后綴備份文件。不備份以~開頭的臨時文件
read -p " What folder should be backed up: " folder
read -p " What type of files should be backed up: " suffix
find $folder -name "*.$suffix" -a ! -name '~*' -exec cp {} \
$BACKUP/$LOGNAME/$folder
echo "Backed up files from $folder to $BACKUP/$LOGNAME/$folder"
自動輸入:
$ echo -e "notes\ndocx\n" | ./backup.sh
Backed up files from notes to /BackupDrive/MyName/notes
echo命令和重定向可以實現交互式輸入的自動化。但這種技術存在問題,因為輸入內容沒有經過驗證,我們認定目標應用總是以相同的順序接收數據。但如果程序要求的輸入順序不同,或是對某些輸入內容不做要求,那就要出岔子了。
expect程序能夠執行復雜的交互操作并適應目標應用的變化。該程序在世界范圍內被廣泛用于控制硬件測試、驗證軟件構建、查詢路由器統計信息等。
expect是一個和shell類似的解釋器。它基于TCL語言。我們將討論如何使用spawn、expect和send命令實現簡單的自動化。借助于TCL語言的強大功能,expect能夠完成更為復雜的任務。
下面的例子會先執行備份腳本,然后查找模式folder或file,以此確定備份腳本是否要求輸入目錄名或文件名并作出相應的回應。如果重寫備份腳本,要求先輸入備份文件類型,后輸入備份目錄,這個自動化腳本依然能夠應對。
#!/usr/bin/expect
#文件名: automate_expect.tcl
spawn ./backup.sh
expect {
"*folder*" {
send "notes\n"
exp_continue
}
"*type*" {
send "docx\n"
exp_continue
}
}
spawn命令的參數是需要自動化運行的應用程序及其參數。
expect命令接受一組模式以及匹配模式時要執行的操作。操作需要放入花括號中。
send命令是要發送的信息。和echo -n -e類似,send不會自動添加換行符,也能夠理解轉義字符。
15.利用并行進程加速命令執行
parallel命令從stdin中讀取文件列表,使用類似于find命令的-exec選項來處理這些文
件。符號{}代表被處理的文件,符號{.}代表無后綴的文件名。
ls *jpg | parallel convert {} -geometry 50x50 {.}Small.jpg
16.檢查目錄以及其中的文件與子目錄
生成目錄的樹狀視圖
find . -exec sh -c 'echo -n {} | tr -d "[:alnum:]_.-" | tr "/" " "; basename {}' ;生成文件及子目錄的匯總信息
for d in `find . -type d`;
do
echo `find $d -type f | wc -l` files in $d;
done