指令:ls、cat、du、rename、dirname、basename、sort、diff、seq、head、tail、tree、chmod、cut、paster、正則
一:統計文件大小,行數,字符數相關命令
統計文件行數、單詞數和字符數
wc file #統計文件行數,單詞數,字符數
wc -l file #統計文件行數
cat file | wc -l #將stdin作為輸入
wc -w file #統計文件單詞數
cat file | wc -w
wc -c file #統計文件字符數
cat file | wc -c
wc file -L #打印最長行的長度
ls -l | grep "^-" | wc -l #統計當前文件夾下的文件個數
ls -lR | grep "^-" | wc -l #遞歸統計當前文件夾下的文件個數(包含子目錄里的)
ls -l | grep "^d" | wc -l #統計當前文件夾下目錄的個數
ls -lR | grep "^d" | wc -l #遞歸統計當前文件夾下目錄的個數(包含子目錄里的)
迭代文件中的行,單詞,字符
1、用子shell迭代行
cat test.txt | ( while read line; do echo $line; done )
2、迭代行再迭代每一行中的每個單詞
while read line;
do
for word in $line
do
if [[ $word == 'test' ]];
then
echo $word;
fi
done
done < test.txt
3、迭代一個單詞中的每一個字符,$(#word)返回變量word的長度,使用特殊標記法 ${string:i:num} string為要迭代的字符串;i為每次迭代的第i個字符;num為從i開始往后取num個字符。
for((i=0;i<${#word};i++))
do
echo ${word:i:1} ;
done
文件大小,操作
du file.txt #查看file.txt占用的磁盤空間,默認以字節作為單位
du file1 file2 file3 ... #查看多個文件的大小
du -a /data/test #查看/data/test目錄下所有文件的大小
du -h file.txt #以KB,MB,GB顯示文件占用的磁盤數更容易閱讀
du -h /data/test #以KB,MB,GB遞歸顯示目錄占用的磁盤數更容易閱讀
du -s file.txt #參數-s表示只輸出合計數據
du -c file1 file2 ... #輸出所有文件占用的磁盤數量,並在最后顯示總數
du -b file #打印以字節為單位的文件大小
du -k file #打印以KB為單位的文件大小
du -m file #打印以MB為單位的文件大小
du -B BLOCK_SIZE file #打印以指定塊為單位的文件大小,如:du -B 4 test.sh
du --exclude "*.txt" /data/test #打印/data/test目錄中處理.txt文件外的所有文件的大小
du --exclude-from list.txt /data/test #打印/data/test目錄總不在list.txt中列出的文件中的文件的大小
du -ak /data/test | sort -nrk 1 | head -n 5 #打印/data/test目錄中最大的5個文件和目錄
find . -type f -exec du -k {} \; | sort -nrk 1 | head #打印當前目錄中最大的10個文件
#判斷文件是否存在
if [[ -s $file ]]; then
echo "not empty"
fi
#判斷文件大小
stat -c %s $file
stat --printf='%s\n' $file
wc -c $file
rename '*.bak' '' *.bak #去掉所有bak后綴
dirname ‘/home/lalor/a.txt' #獲取路徑名 :/home/lalor
basename ‘/home/lalor/a.txt' #獲取文件名 :a.txt
#把所有空格改成下划線
find path -type f -exec rename 's/ /_/g' {} \;
#刪除前3行
$cat a.txt | sed 1,3d
二:文件排序,對比,打印與權限相關命令
排序和去重:sort 與 uniq
sort test.txt test2.txt > sorted.txt #對一個或多個文件以行為單位按照ASCII碼的順序進行排序,再把排序結果從定向到sorted.txt
sort test.txt test2.txt -o sorted.txt #同上
cat sorted.txt | uniq > sort_uniq.txt #對已排序的文件找出不重復的行並重定向到sort_uniq.txt文件
sort test.txt | uniq #排序並去重(重復的行中會保留一行)
sort -u test.txt #同上
sort -n test.txt #參數-n指定按數字進行排序
sort -r test.txt #參數-r指定按逆序進行排序
sort -M test.txt #參數-M指定按月份進行排序
sort -m sorted1.txt sorted2.txt #合並兩個排過序的文件,並且不需要對合並后的文件再進行排序
sort -k 2 test.txt #參數 -k 指定根據第二個鍵(列)進行排序
sort -nk 2,3 test.txt #?
sort -nrk 1 test.txt #將test.txt文件按照第一列的的數字進行逆向排序
sort -z test.txt | xargs -0 #終止符\0使得xargs命令的使用更加安全
sort -bd test.txt #參數-b用戶忽略文件中的前導空白字符,參數-d用戶指明以字典序進行排序
uniq -u test.txt #只顯示唯一的行,(重復的行全部去掉,一行也不保留)
sort test.txt | uniq -u #同上
sort test.txt | uniq -c #排序后統計各行在test.txt文件中出現的次數
sort test.txt | uniq -d #排序后找出test.txt文件中重復的行
sort test.txt | uniq -s 2 -w 3 #使用醒目的字符作為對比的列,通過參數 -s 2 忽略了前2個字符,使用參數 -w 3 指定用於比較的最大字符數為3
echo "ahebhaaa" | sed 's/[^\n]/&\n/g' | sed '/^$/d' | sort | uniq -c | tr -d '\n' #管道 sed 's/[^\n]/&\n/g' 為每個字符后面追加一個換行符;管道 sed '/^$/d' 刪除最后多出的那個換行符;管道 sort 對每一行進行排序(前面這樣做是要拆分成行,因為sort只能進行行排序);管道uniq -c 打印每一行的重復次數; 管道 tr -d '\n' 將輸入中的空格和換行符刪除。結果:4a1b1e2h
----------------------------------------
#!/bin/bash
#測試一個文件是否已經排序
sort -C file ;
if [ $? -eq 0 ]; then
echo Sorted;
else
echo Unsorted;
fi
#要檢查是否按數字進行排序 則使用sort -nC
-----------------------------------------
打印文件行:cat
echo 'Text through stdin' | cat - file.txt #將輸入文件的內容與標准輸入拼接在一起
cat -s filename #壓縮filename文件中連續的多個空白行成單個
cat filename | tr -s '\n' #輸出移除空白行后的filename內容,tr將連續的多個'\n'字符壓縮成單個'\n'
逆序打印行:tac
tac file #逆序打印文件
seq 5 | tac #輸出:54321
file test.txt #確定文件的類型、
文件類型統計信息
---------------------------------------
#!/bin/bash
#filename:test.sh
#執行:./test.sh /data/test
if [ $# -ne 1 ];
then
echo $0 basepath;
echo
fi
path=$1
declare -A statarray;
while read line;
do
ftype=`file -b "$line"`
let statarray["$ftype"]++;
done< <(find $path -type f -print)
echo ================ File types and counts ====================
for ftype in "${!statarray[@]}";
do
echo $ftype : ${statarray["$ftype"]}
done
------------------------------------------
對比文件差異與修補
diff test1.txt test2.txt #test2.txt相對於test1.txt文件多了哪些行少了哪些行。
diff -u test1.txt test2.txt #參數-u用於生成一體化輸出,可讀性更好一點。以+號起始的表示新加入的行,以-號起始的表示刪除的行。
diff -u test1.txt test2.txt > test.patch #(1)將輸出重定向到test.patch文件
patch -p1 test1.txt < test.patch #(2)將修改應用於test1.txt文件,此時test1.txt和test2.txt文件的內容一模一樣。
patch -p1 test1.txt < test.patch #撤銷修改,也可加個-R參數跳過詢問
打印文件
head file #打印文件前10行
cat file | head #同上
head -n 5 file #打印文件前5行
head -n -6 file #打印除了最后6行之外的所有行
seq 11 | head -n -5 #打印除了最后數字7到11這5行之外的所有行,即數字1到6
seq 100 | head -n 5 #打印數字1到5這5行。而不打印數字6到100這95行
tail file #打印文件最后10行
cat file | tail #同上
tail -f file #打印文件最后10行,並隨着數據的增加時時保持更新
tail -n 5 file #打印最后5行
tail -n +(10+1) #打印出了前10行之外的所有行
seq 100 | tail -n +6 #打印除了前5行之外的所有行即第6到第100行。6=N+1,所以N=5
列出文件
ls -d */ #只列出當前目錄下的所有目錄
ls -F | grep "/$" #同上
ls -l | grep "^d" #列出當前目錄下所有目錄的詳細信息
打印目錄
tree path #打印path的目錄樹
tree path -P "*.php" #打印path目錄樹,只顯示目錄樹中的php文件
tree path -I "*.php" #打印path目錄樹,只顯示目錄樹中的除PHP文件外的文件
tree -h path #打印出文件和目錄大小
tree path -H http://localhost -o out.html #生成一個包含目錄樹輸出的HTML文件
文件與目錄權限:
chmod u=rwx g=rw o=x filename #設文件權限,用戶權限為rwx,用戶組權限為rw,其他實體權限為x(u指user,即文件的擁有者;g指group,即文件擁有者所屬的用戶組;o指other,其他)
chmod o+w filename #給其他用戶增加文件的寫權限
chmod g-r filename #刪除用戶組對文件的讀權限
chmod a+x filename #給所有用戶增加文件的執行權限(a指all,表示所有用戶)
chmod a-w filename #刪除所有用戶對文件的寫權限
chmod 755 filename #設置文件的權限為755(r--=4, -w-=2, --x=1;rw-=6,rwx=7,-wx=3,r-x=5),755分別對應user,group,other用戶的權限。
chmod a+t dir_name #設置粘滯位應用於dir_name目錄。(粘滯位是一種應用於目錄的權限類型,使得只有目錄的所有者才能刪除目錄中的文件,即使是用戶組和其他用戶有足夠的權限也不能執行刪除操作)
chmod 755 . -R #遞歸設置當前目錄及子目錄的權限為755
chmod 755 "($pwd)" -R #同上
chown user:group filename #設置文件屬於用戶user,屬於用戶組group
chown user.group filename #同上
chown root:root filename #設置文件屬於root用戶,屬於root用戶組
chmod user:group filename -R #以遞歸方式設置所有權
chattr +i file #設置文件為不可修改
sudo adduser username #增加用戶
sudo deluser username #刪除用戶
passwd #修改當前用戶的密碼
sudo passwd username #修改用戶密碼:
sudo chfn userid #修改用戶資料
sudo usermod -L username #禁用某個帳戶
sudo passwd -l username #禁用某個帳戶
sudo usermod -U username #啟用某個帳戶
sudo passwd -u username #啟用某個帳戶
sudo usermod -G admin -a username #增加用戶到admin組
三:文件切分,合並與重命名相關命令
分割文件:split && csplit
split -b 10k test.txt #將test.txt文件分割為多個文件,每個文件大小為10k,分別以xaa、xab、xac...命名
split -b 10k test.txt -d -a 3 #將test.txt文件分割為多個文件,每個文件大小為10k。參數-d表示以數字為后綴,-a 3 表示后綴長度為3,比如x009,x019,x029,x039...
split -l 100 test.txt #參數-l 100 是指分割成多個文件每個文件包含100行
split -b 10k test.txt -d -a 3 xst #功能與前面相同,但是分割后的文件命名以xst為前綴:xst009、xst019、xst029、xst039...
除了k(KB),其他單位還有M(MB),G(GB),c(byte),w(word)等。
------------------------------------------------------
假設有個文件test.txt:
SERVER-1
aaaaaaaaaaaaaaaaa
bbbbbbbbbbbbbbbbb
ccccccccccccccccc
SERVER-2
ddddddddddddddddd
eeeeeeeeeeeeeeeee
fffffffffffffffff
SERVER-3
gggggggggggggggggg
hhhhhhhhhhhhhhhhhh
iiiiiiiiiiiiiiiiii
csplit test.txt /SERVER/ -n 2 -s {*} -f server -b "%02d.log"
rm server00.log
#/SERVER/ 表示要匹配的文本樣式,包括從當前行(包含)到下一行包含“SERVER”的行(不包含)。
#{*}表示匹配重復分割知道文件結尾。可用{整數}的形式來指定執行分割的次數
# -s 使命令進入靜默模式,不打印其他信息
# -n 指定分割后的文件名后綴的數字個數,例如01,02,03等。
# -f 指定分割后的文件名前綴,-f server 指定前綴為server
# -b 指定后綴格式。-b "%02d.log"
因為分割后的第一個文件沒有任何內容,故刪除。
----------------------------------------------------
文件名切分
------------------------------------
#!/bin/bash
file="test.png" #對於文件名類似file="test.txt.png.log" 這種類型可使用貪婪模式 %% 或者 ##
name=$(file%.*) #文件名切分 %操作符表示非貪婪的刪除位於%右側的通配符所匹配的字符串 貪婪模式:name=${file%%.*}
ext=$(file#*.) #文件擴展名 #操作符表示非貪婪的刪除位於#左側的通配符所匹配的字符串 貪婪模式:ext=$(file##*.)
echo $name,$ext #輸出結果:test,png
------------------------------------
按列切分文件
cut命令:
cut [-bn] [file] 或 cut [-c] [file] 或 cut [-df] [file]
使用說明
cut 命令從文件的每一行剪切字節、字符和字段並將這些字節、字符和字段寫至標准輸出。
如果不指定 File 參數,cut 命令將讀取標准輸入。必須指定 -b、-c 或 -f 標志之一。
主要參數
-b :以字節為單位進行分割。這些字節位置將忽略多字節字符邊界,除非也指定了 -n 標志。
-c :以字符為單位進行分割。
-d :自定義分隔符,默認為制表符。
-f :與-d一起使用,指定顯示哪個區域。
-n :取消分割多字節字符。僅和 -b 標志一起使用。如果字符的最后一個字節落在由 -b 標志的 List 參數指示的<br />范圍之內,該字符將被寫出;否則,該字符將被排除。
cut -f 2,3 filename #顯示文件第2列和第3列
cut -f 2,3,7 filename #顯示文件第2列和第3列和第7列
grep "Invalid user" /var/log/auth.log | cut -d ' ' -f 10 #獲取/var/log/auth.log 中包含“Invalid user”的行,並按照空格拆分行(-d ' ' 參數)獲取第10個字符串(-f 10 參數)
按列合並文件
paste file1 file2 file3 ...
paste test1.txt test2.txt #將test1.txt的每一列與test2.txt的每一列依次拼接起來。
paste test1.txt test2.txt -d "," #參數-d明確指定定界符為逗號
批量重命名文件和移動
-------------------------------------
#!/bin/bash
#批量重命名圖片文件
count=1;
for img in *.jpg *.png #依次取所有的jpg和png文件(.jpg可以改成 .[Jj][Pp][Gg] 從而匹配不區分大小寫)
do
new=image-$count.${img##*.}
mv "$img" "$new" 2> /dev/null # 2> 將mv命令的標准錯誤(stderr)重定向到/dev/null.防止錯誤信息打印到終端
if [$? -eq 0]; # $?用於檢查退出狀態,即最近執行的命令沒有錯誤,$?的值為0.否則$?為非0
then
echo "Renaming $img to $new"
let count++
fi
done
--------------------------------------
rename *.JPG *.jpg #建*.JPG 更名為*.jpg
rename 's/ /_/ge' * #將文件名中的空格替換成字符"_";
rename 'y/A-Z/a-z/' * #轉換文件名為小寫
rename 'y/a-z/A-Z/' * #轉換文件名為大寫
find . -type f -exec rename 's/ /_/ge' {} \; #將所有文件名中的空格替換為字符"_";
for i in `ls`;do mv $i abc_$i;done #當前目錄下所有文件都加上“abc_”前綴
for i in `ls`;do mv $i $(sed -r 's/abc_(.*)/\1/' <<< $i);done #當前目錄下所有文件都去掉“abc_"前綴
四、shell正則表達式
匹配中文字符的正則表達式:[u4e00-u9fa5]
匹配雙字節字符(包括漢字在內):[^x00-xff]
匹配空白行的正則表達式:^ *$
匹配HTML標記的正則表達式:<(S*?)[^>]*>.*?</1>|<.*? />
匹配首尾空白字符的正則表達式:^s*|s*$
匹配Email地址的正則表達式:w+([-+.]w+)*@w+([-.]w+)*.w+([-.]w+)*
匹配網址URL的正則表達式:[a-zA-z]+://[^s]*
匹配帳號是否合法(字母開頭,允許5-16字節,允許字母數字下划線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
匹配國內電話號碼:d{3}-d{8}|d{4}-d{7}
匹配騰訊QQ號:[1-9][0-9]{4,}
匹配中國郵政編碼:[1-9]d{5}(?!d)
匹配身份證:d{15}|d{18}
匹配ip地址:d+.d+.d+.d+
匹配特定數字:
^[1-9]d*$ #匹配正整數
^-[1-9]d*$ #匹配負整數
^-?[1-9]d*$ #匹配整數
^[1-9]d*|0$ #匹配非負整數(正整數+ 0)
^-[1-9]d*|0$ #匹配非正整數(負整數+ 0)
^[1-9]d*.d*|0.d*[1-9]d*$ #匹配正浮點數
^-([1-9]d*.d*|0.d*[1-9]d*)$ #匹配負浮點數
^-?([1-9]d*.d*|0.d*[1-9]d*|0?.0+|0)$ #匹配浮點數
^[1-9]d*.d*|0.d*[1-9]d*|0?.0+|0$ #匹配非負浮點數(正浮點數+ 0)
^(-([1-9]d*.d*|0.d*[1-9]d*))|0?.0+|0$ #匹配非正浮點數(負浮點數+ 0)
匹配特定字符串:
^[A-Za-z]+$ #匹配由26個英文字母組成的字符串
^[A-Z]+$ #匹配由26個英文字母的大寫組成的字符串
^[a-z]+$ #匹配由26個英文字母的小寫組成的字符串
^[A-Za-z0-9]+$ #匹配由數字和26個英文字母組成的字符串
^w+$ #匹配由數字、26個英文字母或者下划線組成的字符串
