ChinaUnix上大神網中人总结的Shell十三问?,强烈推荐,这本书讲得比较精炼,而且都是一些Shell学习中容易把握不住的一些细节难点。每一问都写得非常精彩。 同样是ChinaUnix上,wingger大神整理的Shell基础二十篇。这份文档涉及的内容比较多,我没记错的话应该有很多命令的用法,而且配备实际使用的例子,对初学者帮助甚大。 Shell脚本专家指南也是一本不可多得的好书,我是之前在学校的时候买的这本书。上面都是作者实际工作中的经验总结,你可以从中学到很多其它书上学不到的实践知识。千万不要被专家两个字吓住了,书名的意思是专家给你总结的学习指南。 注:mingxinglai也在他的博客文章shell脚本学习材料种整理了很多实用的资料。 正则表达式 我个人学习正则表达式是从正则表达式30分钟入门教程开始的,这份文档让我了解了正则表达式的一些基础术语和基本的用法。 Linux下的正则表达式学习相对资源比较丰富,但同样得,因为不同工具的正则表达式或多或少都有一些不同,所以初学起来也比较让人困扰,但是正则表达式的关键在于多学多用。多看看grep/sed/awk中正则的用法,慢慢得就熟悉了。 这里推荐一篇InfoQ上介绍Linux下正则表达式不同流派之前的区别的文章——Linux/Unix工具与正则表达式的POSIX规范,读了它之后你会让你有种豁然开朗的感觉。 Sed与awk…
Shell: 删除某时间之前的文件,Argument list too long错误, Remove all files created before a certain date,Argument list too long error

基于 find 来的做:
先了解 find 命令,
- 基于名字搜索
# 单条件 -name只针对文件名 find . -name '*.jpg' -print ./bar/foo.jpg # or 或条件 find . \( -name '*.mp3' -o -name '*.jpg' \) -print ./bar/foo.jpg ./foo.mp3 # and 和条件 find . -name '*.mp3' -name '*.jpg' -print # 复合条件 find . \( -name '*.mp3' -o -name '*.jpg' \) -name 'foo*' -print ./bar/foo.jpg ./foo.mp3 # -path 针对路径 find . -path './bar*' -print ./bar ./bar/foo.jpg # 非 条件 griffon:/tmp/greg$ find . ! -path '*bar*' -print . ./foo.mp3 ./apple.txt
- 基于时间搜索
# 30天之前 find /tmp -mtime +30 -print
- 基于 size 文件大小搜索
# 大于 10 megabytes (10485760 bytes) find /home -type f -size +10485760c -print
搜索并删除
# 30天之前 find /tmp -type f -mtime +30 -exec rm -f {} \; # size 为0 find /tmp -size 0 -type f -name sess_* -exec rm -f {} \; # 1天之前 find /tmp -mtime +1 -type f -name sess_* -exec rm -f {} \;
移动或者修改权限
# 错误或者不合理,可能会导致Argument list too long报错 chmod -R 755 # 正确 find /tmp -type d -exec chmod 755 {} \;
find /tmp -type f -exec chmod 644 {} \;
其他实例:
xargs
is the tool for the job. That, or find
with -exec … {} +
. These tools run a command several times, with as many arguments as can be passed in one go.
Both methods are easier to carry out when the variable argument list is at the end, which isn’t the case here: the final argument to mv
is the destination. With GNU utilities (i.e. on non-embedded Linux or Cygwin), the -t
option to mv
is useful, to pass the destination first.
If the file names have no whitespace nor any of \"'
, then you can simply provide the file names as input to xargs
(the echo
command is a bash builtin, so it isn’t subject to the command line length limit):
echo !(*.jpg|*.png|*.bmp) | xargs mv -t targetdir
You can use the -0
option to xargs
to use null-delimited input instead of the default quoted format.
printf '%s\0' !(*.jpg|*.png|*.bmp) | xargs -0 mv -t targetdir
Alternatively, you can generate the list of file names with find
. To avoid recursing into subdirectories, use -type d -prune
. Since no action is specified for the listed image files, only the other files are moved.
find . -name . -o -type d -prune -o \ -name '*.jpg' -o -name '*.png' -o -name '*.bmp' -o \ -exec mv -t targetdir/ {} +
(This includes dot files, unlike the shell wildcard methods.)
If you don’t have GNU utilities, you can use an intermediate shell to get the arguments in the right order. This method works on all POSIX systems.
find . -name . -o -type d -prune -o \ -name '*.jpg' -o -name '*.png' -o -name '*.bmp' -o \ -exec sh -c 'mv "$@" "$0"' targetdir/ {} +