# commit count
git log --oneline | wc -l
# list add and delete of each file
git log --pretty=tformat: --numstat
# total add and delete
git log --pretty=tformat: --numstat | awk '{ add += $1; subs += $2; loc += $1 - $2 } END { printf "added lines: %s removed lines: %s total lines: %s\n", add, subs, loc }'
awk 是文本处理工具 对git log 筛选出的数据进行处理,$1表示第一列 $2表示第二列,有begin和end.
BEGIN模式表示,在处理指定的文本之前,需要先执行BEGIN模式中指定的动作.
END模式在处理完所有的指定的文本之后,需要指定的动作。

关于 find命令

# 当前目录树下所有扩展名为 .js 的文件,并输出每个匹配文件的相对路径
# 在星号(*)等特殊字符周围打上引号是很重要的,这可以避免 Shell 弄错它们的意义
find . -name '*.js'

# 在当前目录树下,所有与"src"这一名称匹配的目录
# -name 参数对于大小写敏感,如果不需要区分大小写,你应该使用 -iname 参数
# 如果只搜索文件,可以使用 -type f 参数.如果只搜索符号链接,可以使用 -type l 参数
find . -type d -name src

# 在当前目录树下搜索名称为 "node_modules" 或是 'public' 的目录y
find . -type d -name node_modules -or -name public

# 可以用 -not -path 参数排除某个路径
find . -type d -name '*.md' -not -path 'node_modules/*'

# 至少 3 天前编辑的文件
find . -type f -mtime +3

# 最近 24 小时编辑的文件
find . -type f -mtime -1

# 可以使用 -delete 参数同步删除搜索到的文件。比如,下面的命令会删除最近 24 小时编辑的文件
find . -type f -mtime -1 -delete

# if the file is a directory, do not descend into it.
-prune

# To ignore a whole directory tree, use -prune rather than checking every file in the tree.
# For example, to skip the directory 'src/emacs' and all files and directories under it, and print the names of the other files found, do something like this:
find . -path ./src/emacs -prune -o -print

# 避开多个目录, 圆括号是expression的结合, \ 表示引用,指示shell不对后面的字符做特殊解释,留给find去解释其意义
find . \( -path "./bin" -o -path "./doc" \) -prune -o -print

The construct -prune -o \( ... -print0 \) is quite common. 
The idea here is that the expression before -prune matches things which are to be pruned.
However, the -prune action itself returns true, so the following -o ensures that the right hand side
is evaluated only for those directories which did not get pruned (the contents of the pruned directories
are not even visited, so their contents are irrelevant). The expression on the right hand side of the -o is 
in parentheses only for clarity. It emphasises that the -print0 action takes place only for things that 
did not have -prune applied to them. Because the default 'and' condition between tests binds more tightly 
than -o, this is the default anyway, but the parentheses help to show what is going on.


# 查找cache目录下不是html的文件
find ./cache ! -name '*.html' -type f
# 列出当前目录下的目录名,排除includes目录,后面的-print不能少
find . -path './includes' -prune -o -type d -maxdepth 1 -print


# 在/usr/sam目录下查找不在dir1子目录之内的所有文件
find /usr/sam -path "/usr/sam/dir1" -prune -o -print

-path "/usr/sam" -prune -o -print 是 -path "/usr/sam" -a -prune -o -print 的简写表达式按顺序求值, -a 和 -o 都是短路求值。
与 shell 的 && 和 || 类似
如果 -path "/usr/sam" 为真,则求值 -prune, -prune 返回真,与逻辑表达式为真.
如果 -path "/usr/sam" 为假,不求值 -prune, 与逻辑表达式为假.
如果 -path "/usr/sam" -a -prune 为假,则求值 -print,-print返回真,或逻辑表达式为真.

Man手册关于 Expression和Operators的说明。

EXPRESSION
The part of the command line after the list of starting points is the expression. 
This is a kind of query specification describing how we match files and what we do with the files that were matched. 
An expression is composed of a sequence of things:

Tests
	Tests return a true or false value, usually on the basis of some property of a file we are considering. 
	The -empty test for example is true only when the current file is empty.
	
Actions
	Actions have side effects (such as printing something on the standard output)
	and return either true or false, usually based on whether or not they are successful.
	The -print action for example prints the name of the current file on the standard output.
	
Global options
	Global options affect the operation of tests and actions specified on any part of the command line.
	Global options always return true.
	The -depth option for example makes find traverse/遍历 the file system in a depth-first order.
	
Positional options
	Positional options affect only tests or actions which follow them. Positional options always return true.
	The -regextype option for example is positional, specifying the regular expression dialect for regular expressions occurring later on the command line.
	
Operators
	Operators join together the other items within the expression. 
	They include for example -o (meaning logical OR) and -a (meaning logical AND).
	Where an operator is missing, -a is assumed.
	
The -print action is performed on all files for which the whole expression is true, unless it contains an action other than -prune or -quit.
Actions which inhibit the default -print are -delete, -exec, -execdir, -ok, -okdir, -fls, -fprint, -fprintf, -ls, -print and -printf.
The -delete action also acts like an option (since it implies -depth).
OPERATORS
Listed in order of decreasing precedence:

( expr )
	Force precedence. Since parentheses are special to the shell, you will normally need to quote them.
	Many of the examples in this manual page use backslashes for this purpose: `\(...\)' instead of `(...)'.
! expr
	True if expr is false. This character will also usually need protection from interpretation by the shell.
-not expr
	Same as ! expr, but not POSIX compliant.
expr1 expr2
	Two expressions in a row are taken to be joined with an implied -a;
	expr2 is not evaluated if expr1 is false.
expr1 -a expr2
	Same as expr1 expr2.
expr1 -and expr2
	Same as expr1 expr2, but not POSIX compliant.
expr1 -o expr2
	Or; expr2 is not evaluated if expr1 is true.
expr1 -or expr2
	Same as expr1 -o expr2, but not POSIX compliant.
expr1 , expr2
	List; both expr1 and expr2 are always evaluated.
	The value of expr1 is discarded; the value of the list is the value of expr2.
	The comma operator can be useful for searching for several different types of thing, but traversing the filesystem hierarchy only once.
	The -fprintf action can be used to list the various matched items into several different output files.

Please note that -a when specified implicitly (for example by two tests appearing without 
an explicit operator between them) or explicitly has higher precedence than -o.
This means that find . -name afile -o -name bfile -print will never print afile.