Home | 簡體中文 | 繁體中文 | 雜文 | 知乎專欄 | Github | OSChina 博客 | 雲社區 | 雲棲社區 | Facebook | Linkedin | 視頻教程 | 打賞(Donations) | About
知乎專欄多維度架構 微信號 netkiller-ebook | QQ群:128659835 請註明“讀者”

26.4. Directory and File System Related

26.4.1. dirname

$ dirname /usr/bin/find
/usr/bin
    	

26.4.2. filename

$ basename /usr/bin/find
find
    	

26.4.2.1. 排除副檔名

file=test.txt
b=${file%.*}
echo $b
	    	
$ for file in *.JPG;do mv $file ${file%.*}.jpg;done
	    	

26.4.2.2. 取副檔名

file=test.txt
b=${file##*.}
echo $b
	    	

26.4.3. test - check file types and compare values

		
test -x /usr/bin/munin-cron && /usr/bin/munin-cron
		
		

26.4.4. file — determine file type

$ file mis.netkiller.cn-0.0.1.war 
mis.netkiller.cn-0.0.1.war: Zip archive data, at least v2.0 to extract

$ file dian_icon.png 
dian_icon.png: PNG image data, 8 x 24, 8-bit/color RGBA, non-interlaced

$ file sms-s3.jpg
sms-s3.jpg: JPEG image data, JFIF standard 1.01

$ file -i favicon.ico 
favicon.ico: image/x-icon; charset=binary

$ file netkiller.wmv 
netkiller.wmv: Microsoft ASF

$ file netkiller.flv
netkiller.flv: Macromedia Flash Video

$ file neo.swf
neo.swf: Macromedia Flash data (compressed), version 10

$ file cs800.css 
cs800.css: ISO-8859 text, with CRLF line terminators
		

查看mime

$ file -i sms.jpg
sms.jpg: image/jpeg; charset=binary

$ file -i call.png
call.png: image/png; charset=binary

$ file -i cs800.css
cs800.css: text/plain; charset=iso-8859-1

$ file -i neo.swf
neo.swf: application/x-shockwave-flash; charset=binary

$ file -i neo.wmv
neo.wmv: video/x-ms-asf; charset=binary

$ file -i neo.flv
neo.flv: video/x-flv; charset=binary
		

26.4.5. stat

modification time(mtime,修改時間):當該檔案的“內容數據”更改時,會更新這個時間。內容數據指的是檔案的內容,而不是檔案的屬性。
status time(ctime,狀態時間):當該檔案的”狀態(status)”改變時,就會更新這個時間,舉例,更改了權限與屬性,就會更新這個時間。
access time(atime,存取時間):當“取用檔案內容”時,就會更新這個讀取時間。舉例來使用cat去讀取該檔案,就會更新atime了。
		
[root@apache www]# stat index.html
  File: `index.html'
  Size: 145355          Blocks: 296        IO Block: 4096   regular file
Device: fd01h/64769d    Inode: 15861815    Links: 1
Access: (0755/-rwxr-xr-x)  Uid: (  502/  upuser)   Gid: (  502/  upuser)
Access: 2010-10-28 11:09:52.000000000 +0800
Modify: 2010-10-28 10:23:13.000000000 +0800
Change: 2010-10-28 10:23:13.000000000 +0800
		

26.4.6. mkdir - make directories

mkdir -p /tmp/test/{aaa,bbb,ccc,ddd}

mkdir -p /tmp/test/{aaa,bbb,ccc,ddd}/{eee,fff}

mkdir -p /tmp/test/{2008,2009,2010,2011}/{01,02,03,04,05,06,07,08,09,10,11,12}/{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30}
		

26.4.7. rename

批量更改副檔名

rename 's/\.png/\.PNG/' *.png

rename '/\.mp3/\.MP3/' *.mp3
rename .mp3 .MP3 *.mp3

rename GIF gif *.GIF
		
for file in *.GIF
do
        mv $file ${file%.*}.gif
done
		
$ mkdir chapter.command.xxx.xml
$ mkdir chapter.command.bbb.xml
$ mkdir chapter.command.ccc.xml
$ mkdir chapter.command.ddd.xml

$ rename 's/command/cmd/' *.command.*.xml
		

26.4.8. touch

創建空檔案,修改檔案日期時間

touch [-acdmt] 檔案
參數:
-a : 僅修改access time。
-c : 僅修改時間,而不建立檔案。
-d : 後面可以接日期,也可以使用 --date="日期或時間"
-m : 僅修改mtime。
-t : 後面可以接時間,格式為 [YYMMDDhhmm]

# touch filename
# touch -d 20050809 filename
# touch -t 0507150202 bashrc
# touch -d "2 days ago" bashrc
# touch --date "2011-06-03" filename
		

26.4.9. truncate

truncate - shrink or extend the size of a file to the specified size

創建指定大小的檔案

truncate -s 1k /tmp/test.txt
truncate -s 100m /tmp/test100.txt	
		

26.4.10. ls - list directory contents

$ ls
$ ls ~
$ ls -l
$ ls -a
$ ls -1
$ ls -F
bg7nyt.txt*  Desktop/    Firefox_wallpaper.png  Music/     public_html@  Videos/
bg7nyt.wav*  Documents/  Mail/                  nat.txt*   script/       workspace/
BOINC/       Examples@   mbox                   Pictures/  Templates/
		

{}通配符

ls {*.py,*.php,*.{sh,shell}}
		

take a look at below

alias l='ls -CF'
alias la='ls -A'
alias ll='ls -l'
alias ls='ls --color=auto'
		

26.4.10.1. full-time / time-style 定義日期時間格式

預設風格

[www@www.netkiller.cn ~]$ ls -l /var/log/message*
-rw------- 1 root root 302533 Jun 18 09:50 /var/log/messages
-rw------- 1 root root 392028 May 23 03:30 /var/log/messages-20160523
-rw------- 1 root root 334328 May 29 03:09 /var/log/messages-20160529
-rw------- 1 root root 395792 Jun  5 03:44 /var/log/messages-20160605
-rw------- 1 root root 308984 Jun 13 03:33 /var/log/messages-20160613
			

修改後

--full-time = --time-style=full-iso

[www@www.netkiller.cn ~]$ ls -l --full-time /var/log/messages*
-rw------- 1 root root 308659 2016-06-18 10:24:49.186979051 +0800 /var/log/messages
-rw------- 1 root root 392028 2016-05-23 03:30:01.869219181 +0800 /var/log/messages-20160523
-rw------- 1 root root 334328 2016-05-29 03:09:02.158442470 +0800 /var/log/messages-20160529
-rw------- 1 root root 395792 2016-06-05 03:44:02.424073354 +0800 /var/log/messages-20160605
-rw------- 1 root root 308984 2016-06-13 03:33:02.004785063 +0800 /var/log/messages-20160613

[www@www.netkiller.cn ~]$ ls -l --time-style=full-iso /var/log/messages*
-rw------- 1 root root 308659 2016-06-18 10:24:49.186979051 +0800 /var/log/messages
-rw------- 1 root root 392028 2016-05-23 03:30:01.869219181 +0800 /var/log/messages-20160523
-rw------- 1 root root 334328 2016-05-29 03:09:02.158442470 +0800 /var/log/messages-20160529
-rw------- 1 root root 395792 2016-06-05 03:44:02.424073354 +0800 /var/log/messages-20160605
-rw------- 1 root root 308984 2016-06-13 03:33:02.004785063 +0800 /var/log/messages-20160613
			

long-iso

[www@www.netkiller.cn ~]$ ls -lh --time-style long-iso /var/log/message*
-rw------- 1 root root 296K 2016-06-18 10:00 /var/log/messages
-rw------- 1 root root 383K 2016-05-23 03:30 /var/log/messages-20160523
-rw------- 1 root root 327K 2016-05-29 03:09 /var/log/messages-20160529
-rw------- 1 root root 387K 2016-06-05 03:44 /var/log/messages-20160605
-rw------- 1 root root 302K 2016-06-13 03:33 /var/log/messages-20160613			
			

通過配置 TIME_STYLE 環境變數,改變日期格式

[www@www.netkiller.cn ~]$ export TIME_STYLE=long-iso

[www@www.netkiller.cn ~]$ ls -l /var/log/message*
-rw------- 1 root root 302533 2016-06-18 09:50 /var/log/messages
-rw------- 1 root root 392028 2016-05-23 03:30 /var/log/messages-20160523
-rw------- 1 root root 334328 2016-05-29 03:09 /var/log/messages-20160529
-rw------- 1 root root 395792 2016-06-05 03:44 /var/log/messages-20160605
-rw------- 1 root root 308984 2016-06-13 03:33 /var/log/messages-20160613
			
[www@www.netkiller.cn ~]$ export TIME_STYLE=iso
[www@www.netkiller.cn ~]$ ls -l /var/log/message*
-rw------- 1 root root 302533 06-18 09:50 /var/log/messages
-rw------- 1 root root 392028 05-23 03:30 /var/log/messages-20160523
-rw------- 1 root root 334328 05-29 03:09 /var/log/messages-20160529
-rw------- 1 root root 395792 06-05 03:44 /var/log/messages-20160605
-rw------- 1 root root 308984 06-13 03:33 /var/log/messages-20160613
			

自定義格式

[www@www.netkiller.cn ~]$ ls -l --time-style="+%Y-%m-%d" /var/log/message*
-rw------- 1 root root 302533 2016-06-18 /var/log/messages
-rw------- 1 root root 392028 2016-05-23 /var/log/messages-20160523
-rw------- 1 root root 334328 2016-05-29 /var/log/messages-20160529
-rw------- 1 root root 395792 2016-06-05 /var/log/messages-20160605
-rw------- 1 root root 308984 2016-06-13 /var/log/messages-20160613

[root@www.netkiller.cn ~]# export TIME_STYLE='+%Y/%m/%d %H:%M:%S'
[root@www.netkiller.cn ~]# ls -l /var/log/messages*
-rw------- 1 root root 189352 2016/06/18 10:20:01 /var/log/messages
-rw------- 1 root root 322453 2016/05/22 03:48:02 /var/log/messages-20160522
-rw------- 1 root root 247398 2016/05/30 03:37:01 /var/log/messages-20160530
-rw------- 1 root root 174633 2016/06/05 03:14:02 /var/log/messages-20160605
-rw------- 1 root root 196728 2016/06/12 03:17:01 /var/log/messages-20160612
			

26.4.11. cp - copy files and directories

26.4.11.1. copy directories recursively

cp -r /etc/* ~/myetc
			

26.4.11.2. overwrite an existing file

# alias cp
alias cp='cp -i'

# unalias cp
# alias cp
-bash: alias: cp: not found
			

26.4.11.3. -a, --archive same as -dR --preserve=all

# cp -a file file2
			

-a 參數可以保留原檔案的日期與權限等等信息。

# ll
-rw-r--r--. 1 root root      2559 Aug 27 05:00 yum.sh

# cp -a yum.sh yum1.sh
# cp yum.sh yum2.sh

# ll yum*
-rw-r--r--. 1 root root 2559 Aug 27 05:00 yum1.sh
-rw-r--r--. 1 root root 2559 Aug 27 05:58 yum2.sh
-rw-r--r--. 1 root root 2559 Aug 27 05:00 yum.sh
			

現在可以看到 yum1.sh 與 yum.sh 日期是相同的,而沒有實現-a參數的 yum2.sh 日期為當前日期。

26.4.12. rm - remove files or directories

26.4.12.1. -bash: /bin/rm: Argument list too long

ls -1 | xargs rm -f
find . -name 'spam-*' | xargs rm
find . -exec rm {} \;

ls | xargs -n 10 rm -fr # 10個為一組
			

26.4.12.2. zsh: sure you want to delete all the files in /tmp [yn]?

yes | rm -i file
			

26.4.13. df - report file system disk space usage

neo@netkiller:~$ df -lh
Filesystem            Size  Used Avail Use% Mounted on
/dev/sda1              19G  3.1G   15G  17% /
none                  996M  224K  996M   1% /dev
none                 1000M     0 1000M   0% /dev/shm
none                 1000M  520K 1000M   1% /var/run
none                 1000M     0 1000M   0% /var/lock
none                 1000M     0 1000M   0% /lib/init/rw
/dev/sda6              19G   13G  4.5G  75% /home
/dev/sda10            556M  178M  351M  34% /boot
/dev/sda7              46G  4.4G   40G  10% /var
/dev/sda8             367G   60G  289G  18% /opt
/dev/sda9             6.5G  143M  6.0G   3% /tmp
		

26.4.14. du - estimate file space usage

neo@netkiller:~$ sudo du -sh /usr/local
63M     /usr/local
		

26.4.15. tac - concatenate and print files in reverse

$ tac /etc/issue
Kernel \r on an \m
CentOS release 5.4 (Final)
		

26.4.16. split - split a file into pieces

26.4.16.1. 按行分割檔案

-l, --lines=NUMBER put NUMBER lines per output file

每10000行產生一個新檔案

# split -l 10000 book.txt myfile		
			

26.4.16.2. 按尺寸分割檔案

-b, --bytes=SIZE put SIZE bytes per output file

下面的例子是每10兆分割為一個新檔案

split -b 10m large.bin new_file_prefix			
			

26.4.17. find - search for files in a directory hierarchy

26.4.17.1. name

Find every file under directory /usr ending in "stat".

$ find /usr -name *stat
/usr/src/linux-headers-2.6.24-22-generic/include/config/cpu/freq/stat
/usr/bin/lnstat
/usr/bin/sar.sysstat
/usr/bin/mpstat
/usr/bin/rtstat
/usr/bin/nstat
/usr/bin/lpstat
/usr/bin/ctstat
/usr/bin/stat
/usr/bin/kpsestat
/usr/bin/pidstat
/usr/bin/iostat
/usr/bin/vmstat
/usr/lib/sysstat
/usr/share/doc/sysstat
/usr/share/gnome/help/battstat
/usr/share/omf/battstat
/usr/share/zsh/help/stat
/usr/share/zsh/4.3.4/functions/Completion/Unix/_diffstat
/usr/share/zsh/4.3.4/functions/Completion/Zsh/_stat
/usr/share/zsh/4.3.4/functions/Zftp/zfstat
		
find  \( -iname '*.jpg' -o -iname '*.png' -o -iname '*.gif'  \)

find /www/images -type f \( -iname '*.js' -o -iname '*.css' -o -iname '*.html' \) | xargs tar -czf ~/images.tgz
		

使用通配符

find . -name "*.jsp" -delete
find . -name "*.xml" -delete		
		

26.4.17.2. regex

find . -regex ".*\.\(jpg\|png\)"
		

下面regex與name作用相同

find . -regex ".*\.\(txt\|sh\)"
find . -name "*.sh" -o -name "*.txt"
		

-regex參數,使用正則表達式來匹配. 查找當前目錄以及子目錄中以 ".sh",並改為以".shell"結尾.

		
[neo@netkiller test]# tree a
a
├── a.py
├── a.sh
└── b
    ├── b.py
    ├── b.sh
    ├── c
    │   └── c.sh
    └── d
        └── d.sh

[neo@netkiller test]# find ./a -type f  -regex ".*\.sh$" | sed -r -n 's#(.*\.)sh$#mv & \1shell#e'
[neo@netkiller test]# tree a
a
├── a.py
├── a.shell
└── b
    ├── b.py
    ├── b.shell
    ├── c
    │   └── c.shell
    └── d
        └── d.shell
        
 // 注意 sed s->e  使用方式,官方文檔是這樣解釋的.
This command allows one to pipe input from a shell command into pattern space. If a substitution was made, the command that is found in pattern space is executed and pattern space is replaced with its output. A trailing newline is suppressed; results are undefined if the command to be executed contains a NUL character. This is a GNU sed extension.
		
		

26.4.17.3. user

Find every file under /home and /var/www owned by the user neo.

$ find /home -user neo
$ find /var/www -user neo
$ find . -user nobody -iname '*.php'
		

26.4.17.4. perm

find ./ -perm -7 -print | xargs chmod o-w
find . -perm -o=w
		

查找當前目錄下權限為777的檔案並顯示到標準輸出

find ./ -type f -perm 777 -print		
		

26.4.17.5. type

26.4.17.5.1. 分別設置檔案與目錄的權限
find /usr/www/phpmyadmin -type d -exec chmod 755 {} \;
find /usr/www/phpmyadmin -type f -exec chmod 644 {} \;
			

26.4.17.6. -delete

# find /var/spool/clientmqueue/ -type f -delete
		

保留最近7天的問題,其他全部刪除

find . -type f -mtime +7 -delete
		

26.4.17.7. exec

替換文本

# find ./ -exec grep str1 ‘{}’ \; -exec sed -i.bak s/str1/str2/g ‘{}’ \;
		
find -exec ls -l {} \; | grep '2011-01-18'
		

查找*.html檔案中aaa替換為bbb

find . -name "*.html" -type f -exec sed -i "s/aaa/bbb/" {} \;		
		

查找檔案中含有openWindow字元串的檔案

# find -type f -name "*.js" -exec grep -H -A2 openWindow {} \;

./javascript/commonjs.js:function openWindow(url){
./javascript/commonjs.js-	window.open(url + "?rand=" + getRandom(), 'gamebinary');
./javascript/commonjs.js-}
		
find -type f -regex ".*\.\(css\|js\)" -exec yuicompressor {} -o {} \;
find -type f -name "*.js" -exec yuicompressor --type js {} -o {} \;
find -type f -name "*.css" -exec yuicompressor --type css {} -o {} \;
		

26.4.17.8. 排除目錄

find /usr/local -path "/usr/local/share" -prune -o -print

find /usr/local \( -path /usr/local/bin -o -path /usr/local/sbin \) -prune -o -print

find /usr/local \(-path /usr/local/dir1 -o -path /usr/local/file1 \) -prune -o -name "temp" -print
		

查找當前目錄下的php檔案,排除子目錄templates_c, caches

find . \( -path ./templates_c -o -path ./caches \) -prune -o -name "*.php" -print
		

26.4.17.9. -mmin n File's data was last modified n minutes ago.

# find . -mmin +5 -mmin -10
		
find /www -type f -mtime +60s
		

26.4.17.10. -ctime

查找當前目錄下超過6天且是空檔案並刪除

find ./ -type d -empty -ctime +6 -exec rm -f {} \;	
		

查找7天前的檔案並刪除

find /backup/svn/day -type f -ctime +7 -exec rm -f {} \; 
find /backup/svn/day -type f -ctime +7 -delete
find /backup/svn/day -type f -ctime +7 | xargs rm -f	
		

26.4.17.11. -mtime / -mmin

查詢最近3天前內修改的檔案

find . -type f -mtime -3
		

3天前

find . -type f -mtime +3
		

例 26.1. backup(find + tar)

find / -type f -mtime -7 | xargs tar -rf weekly_incremental.tar
gzip weekly_incremental.tar
			

保留7天,刪除7天的日誌檔案

COPIES=7
find /var/log -type f -mtime +$COPIES -delete
		

26.4.17.12. --newer

tar --newer="2011-07-04" -zcvf backup.tar.gz /var/www/
tar cvzf foo.tgz /bak -N "2004-03-03 16:49:17"
		

26.4.17.13. -print / -printf

[root@scientific ~]# find / -maxdepth 1 -name '[!.]*' -printf 'Name: %16f Size: %6s\n'
Name:                / Size:   4096
Name:             misc Size:      0
Name:            media Size:   4096
Name:             home Size:   4096
Name:              dev Size:   3840
Name:              net Size:      0
Name:             proc Size:      0
Name:             sbin Size:  12288
Name:             root Size:   4096
Name:              lib Size:   4096
Name:           cgroup Size:   4096
Name:              srv Size:   4096
Name:              mnt Size:   4096
Name:              etc Size:  12288
Name:              usr Size:   4096
Name:            lib64 Size:  12288
Name:             boot Size:   1024
Name:              var Size:   4096
Name:          selinux Size:      0
Name:              opt Size:   4096
Name:              tmp Size:   4096
Name:       lost+found Size:  16384
Name:              sys Size:      0
Name:              bin Size:   4096

# find /etc/ -type f -printf "%CY-%Cm-%Cd %Cr %8s %f\n"
		

26.4.17.14. -size

查找0位元組檔案

find /www -type f -size 0
		

查找根目錄下大於1G的檔案

find /  -type f -size +1000M		
		

26.4.17.15. -path

搜索當前目錄下除了keys目錄下所以子目錄中的檔案

find ./ -path "./keys" -prune -o -type f -print 		
		

find排除多個目錄

find ./ \( -path ./conf -o -path ./logs \) -prune -o -print

find /data/ \( -path /data/data_backup -o -path /data/mysql \) -prune -o -name "core.*" -type f 
/data/mysql
/data/data_backup		
		

ps 要麼都是絶對路徑 要麼都是相對路徑 /data/ 必須有"/" path 後面的路徑必須沒有"/"

26.4.17.16. 目錄深度控制

		
neo@MacBook-Pro ~/workspace/Linux % find */images -type d -d 0 -exec echo {} \;
Cryptography/images
Monitoring/images
OpenLDAP/images
Project/images
Web/images
		
		
		
find */images -type d -d 0 -exec rsync -au {}/* $(PUBLIC_HTML)/linux/images \; 		
		
		

26.4.17.17. -maxdepth

-maxdepth和-mindepth,最大深度,最小深度搜索,搜索當前目錄下最大深度為1的所以檔案

find . -maxdepth 1 -type f 		
		

26.4.17.18. xargs

find /etc -type f|xargs md5sum
		

sha1sum

find /etc -type f|xargs sha1sum
		
find ./ -name "*html" | xargs -n 1 sed -i -e 's/aaa/bbb/g'
		
find /tmp -name core -type f -print | xargs /bin/rm -f
find . -type f -exec file '{}' \;
		

find後執行xargs提示xargs: argument line too long解決方法:

find . -type f -name "*.log" -print0 | xargs -0 rm -f