2015年8月8日 星期六

Linux 'find' handbook

#Exclude a directory in find . command
find . -path ./misc -prune -o -name '*.txt'
find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -prune -o -print
find / -xdev -name p2p_supplicant.conf

#List all .bin (case ignored) and .txt (case sensitivity) files in /fooA and /fooB folders.
find /fA /fB -type f -iname "*.bin" -name "*.txt"
find -name "[a-z]*[4-9].log"
Copy all .txt files in /foo to ~/txt folder.
find /foo -type f -name "*.txt" -exec cp {} ~/txt \;
Remove all .git folders in /foo 
find /foo -type d -name ".git" -exec rm -fr {} \;    


List all hidden folders/files in /foo 
find /foo -name ".*" -ls    

# Find files and tar them (with spaces)
# It will:
#   + deal with files with spaces, newlines, leading dashes, and other funniness
#   + handle an unlimited number of files
#   + won't repeatedly overwrite your backup.tar.gz like 
#       using tar -c with xargs will do when you have a large number of files.
find . -type f -print0 | tar -czvf backup.tar.gz --null -T -
# Find files and open them in gedit.
find . -name '*.foo' -exec gedit {} +

# Find symbolic links but those inside .git folders and count.
find . ! -path "*/.git/*" -type l | wc -l
find . ! -path "*/.git/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"

Find files by text in the file (find + grep)
----------------------------------------------------------------------------------------------
# Find StringBuffer in all *.java files 
find -type f -name "*.java" -exec grep -l StringBuffer {} \;
# ignore case with -i option 
find -type f -name "*.java" -exec grep -il string {} \;
# search for a string in gzip'd files
find -type f -name "*.gz" -exec zgrep 'GET /foo' {} \;        


Find files by modification time
---------------------------------------------------------------------------------------------- 
find -newer A.log ! -newer B.log     # newer than A.log but no newer than B.log
find . -mtime 1                                 # 24 hours 
find . -mtime -7                                # last 7 days
touch -t YYMMDDhhmm.SS /tmp/timestamp
find directory -type f -newer /tmp/timestamp
rm /tmp/timestamp
touch –date "2012-11-07" /tmp/find_after
find / -newer /tmp/find_after
rm /tmp/find_after

Find files by user/group
---------------------------------------------------------------------------------------------- 
find /etc -user peida
find /home -nouser
find /apps -group sudo
find /apps -nogroup
find -perm 755                                # List all files/folders of permission 755
find /dir -type d -iname ".*" -ls      # List all files/folders in hidden folders.

find \! -user foo -print                     # List items NOT owned by user foo.

Find files by size,folder depth,partition
---------------------------------------------------------------------------------------------- 
find -size +1000000c                      # list items of size larger than 10^6 bytes.
find -name A*.txt -depth                 # list in the same depth and then subfolders.
find -name *.XC -mount                  # only for the same partition.


Error handling
----------------------------------------------------------------------------------------------
#ERROR find: paths must precede expression
find . -name "*.log"                     
#Handle file with space in its name.  ('find' treats SPACE, TAB, and NEWLINE as delimiter by default)
find . -name "*.log" -print0 | xargs -0 cat           #'-print0' append 0 rather than NEWLINE to the output string.  '-0' takes only 0 as delimiter.
find . -name "*.log" -print0 | xargs -d "\\n" cat  # ' -d "\\n" ' takes only NEWLINE as delimiter.

#Skip “Permission denied” errors
source: https://unix.stackexchange.com/questions/42841/how-to-skip-permission-denied-errors-when-running-find-in-linux
find / -name art  2>&1 | grep -v "Permission denied"
Explanation:
In short, all regular output goes to standard output (stdout). All error messages to standard error (stderr).
grep usually finds/prints the specified string, the -v inverts this, so it finds/prints every string that doesn't contain "Permission denied". All of your output from the find command, including error messages usually sent to stderr (file descriptor 2) go now to stdout(file descriptor 1) and then get filtered by the grep command.
This assumes you are using the bash/sh shell.
Under tcsh/csh you would use
 find / -name art |& grep ....


To Be Sorted

---------------------------------------------------------------------------------------------- 
删除以html结尾的10天前的文件,包括带空格的文件:
find /usr/local/backups -name "*.html" -mtime +10 -print0 |xargs -0 rm -rfv
find /usr/local/backups -mtime +10 -name "*.html" -exec rm -rf {} \;

find -print 和 -print0的区别:
-print 在每一个输出后会添加一个回车换行符,而-print0则不会。

当前目录下文件从大到小排序(包括隐藏文件),文件名不为".":
find . -maxdepth 1 ! -name "." -print0 | xargs -0 du -b | sort -nr | head -10 | nl
nl:可以为输出列加上编号,与cat -n相似,但空行不编号
以下功能同上,但不包括隐藏文件:
for file in *; do du -b "$file"; done|sort -nr|head -10|nl

xargs结合sed替换:
find . -name "*.txt" -print0 | xargs -0 sed -i 's/aaa/bbb/g'

xargs结合grep:
find . -name '*.txt' -type f -print0 |xargs -0 grep -n 'aaa' #“-n”输出行号

Find things by name

 # find /path/to/search -name filename

Example
 # find /etc -name hosts
  /etc/hosts

Find things by name (case-insensitive)

 # find /path/to/search -iname filename

Example
 # find /etc -iname HOSTS
  /etc/hosts

Find only files by name

 # find /path/to/search -name filename -type f

Example
 # find /etc -name network* -type f
  /etc/init/networking.conf

Find only directories by name

 # find /path/to/search -name dirname -type d

Example
 # find /etc -name network* -type d
  /etc/apparmor/init/network-interface-security

Find all symlinks

 # find /path/to/search -type l

Example
 # find /etc -type l
  /etc/vtrgb

Find things by owner

 # find /path/to/search -user owner

Example
 # find ./ -user root
  ./
  ./log.file

Find executable files

 # find /path/to/search -type f -executable

Example
 # find ./ -type f -executable
 ./4/2651.file

Find SUID files

 # find /path/to/search -perm -4000

Example
 # find /sbin -perm -4000
 /sbin/mount.ecryptfs_private

Find things changed today

 # find /path/to/search -daystart -ctime -1

Example
 # find ./ -daystart -ctime -1
  ./

Find things changed in the last 24 hours

 # find /path/to/search -ctime -1

Example
 # find ./ -ctime -1
  ./

Counting how many things you find

 # find /path/to/search | wc -l

Example
 # find ./ | wc -l
  14674

Deleting things you find

 # find /path/to/search -delete

Deleting things you find (with xargs)

 # find /path/to/search | xargs rm

Deleting things you find (with exec)

 # find /path/to/search -exec rm {} ;

Printing Type of file, Filename & Inode

 # find /path/to/search -printf "%y %i %prn"

Example
 # find ./ -printf "%y %i %prn"
  d 4852409 ./

Finding Broken Symlinks

 # find /path/to/search -follow -lname "*"

Example
 # find ./ -follow -lname "*"
  ./bad_link

Find files older than 31 days and delete them

 # find /path/to/search -mtime +31 -delete

Example
 # find ./ -mtime +31
  ./sudoers.new
  ./file.symlink
  ./somedirectory
  ./play/list.txt2
  ./tar.tgz
  # find ./ -mtime +31 -delete
  # find ./ -mtime +31

Remove Empty Directories

 # find /path/to/search -type d -exec rmdir --ignore-fail-on-non-empty {} + ;

Tar files changed today

 # tar -cvzf ../files_created_today.tgz `find /path/to/search -type f -daystart -ctime -1`

Find files bigger than X Size

 # find /path/to/search -size +

Example
 # find ./ -size +100M
 ./madflojo/Downloads/ubuntu-12.04-server-amd64.iso

Using Regex with find

 # find /path/to/search -regex 'regex pattern (full path)'

Example
 # find /var -regex '.*/tmp/.*[0-9]*.file'
 /var/tmp/testing/2/914.file

沒有留言: