关于Shell的一些常用命令

jopen 9年前

ls -lat 列出当前目录所有东东的东东
ls -lath 人看的大小
ls -F | grep "/$"只搞目录
ls -lR 包括子目录…
ls --ignore filename -lt 忽略某个


which,在PATH变量指定的路径中,搜索看某个命令是否存在,以及执行的到底是哪一个位置的命令。
whereis, 搜索程序名,而且只搜索二进制文件、man说明文件和源代码文件。如果省略参数,则返回所有信息。
locate,在系统特定的数据库中指定文件名查找,譬如CentOS它只在每天某个时间把新增的文件更新到/var/lib/mlocate /mlocate.db这个数据库,定时见/etc/cron.daily/mlocate.cron,strings可以看到部分内容
还有一些好用的工具如tree,file,type等


-mtime 修改时间
-type 文件类型
-mmin 修改分钟
-perm 权限
-user 用户
-group 组
-maxdepth 搜索目录的层级

更多的东西请找你男人,man



find . -maxdepth 1 -type f  ! -name "*.txt"
在层级为1的目录(当前目录)查找不是.txt的普通文件
find . -maxdepth 1 -type f  \( -name "*.txt" ! -name "haha.txt" \)
查找.txt但不包括类似.haha.txt这样的文件
find . -maxdepth 1 -type f  \( -name "*.php" -o -name "*.txt" \)
查找.php或者.txt的文件


-exec会将find匹配到的所有文件一次性接收过来操作,不幸的是,有些系统对能够传递给 exec的命令长度有限制,会出现溢出错误,譬如提示"Argument list too long"
getconf ARG_MAX 看看参数的字节限制
那怎么办?


xargs xargs命令每次只获取一部分文件而不是全部,不像 -exec选项那样。这样它可以先处理 最先获取的一部分文件,然后是下一批,并如此继续下去。
find . -name "*.txt" | xargs -n 200 ls -lat
find . -name "*.txt" | xargs -I file -n 1 mv file file.log  更好理解的表达


find查找避开某个目录
find . -path "./subdir*" -prune -o  -type f -name "*.txt" -print
查找/update/目录下但不包括子目录./subdir下面的东西
上面是啥意思? 个人理解:
别被-path迷惑,其实-path就是-wholename,在这里用-wholename  "./subdir*" 一样的。
-depth与-prune冲突,有-depth的话-prune失效
可以用伪代码表示:
find ... 得到好长好长一串。。。
在这好长一串里
if (-path "./subdir*")
then
          -prune #切切切
else (找-type f -name "*.txt")
          -print
避开多个目录
find . -path './subdir' -prune -o -path './subdir1' -prune -o -path './subdir2' -prune -o -path './subdir3' -prune -o -name "*.txt" -print
简写成下面的:
find .  \( -path './subdir' -o -path './subdir1'  -o -path './subdir2'  -o -path './subdir3'  \) -prune -o -name "*.txt" -print


 grep -n a *.txt
显示匹配行及行号
 grep -c a *.txt
只输出匹配行的计数
 grep -v a *.txt
不包含匹配
 grep '\<abcd\>' *.txt 
精确匹配a
grep '[A-Z][a-z][0-9]' *.txt
打印类似"Ab1"的内容,支持posix正则
 grep '[a-z]\{4,\}log' *.txt
打印小写字母重复四次以上的行,如aaaa,aabbc等
 grep -v '^$|^#' *.txt
过滤空行与#开头的行(通常是注释)
grep –A5 –B5 'haha' *.txt
打印匹配到'haha'的行以及上5行、下5行
grep '192.168.100.34:3306|pfantasy' –R /usr/local/wwwroot/ 
也可以写成egrep -e '192.168.100.34:3306' -e 'pfantasy' -R /usr/local/wwwroot/
 grep '192.168.100.34:3306.*pfantasy' -R /usr/local/wwwroot/


awk语句都由模式和动作组成
模式部分决定找对象的时机,一般由条件语句或者正则组成,包括两个特殊字段:BEGIN{}和END{}
动作就是在某些情况下该干些啥。。。
BEGIN{} 在任何文本浏览动作之前,一般用作制表,END{} 用来在完成文本浏览后,通常用作统计
因此一般的结构是:awk 'BEGIN{预定义点啥}{正式干点啥}{又干点啥}...END{干完了总结汇报点啥}'


$1 $2 $3 ... 
$0代表全部,动作缺省情况下打印全部
通常域的分隔符是空格或者\t
awk 'BEGIN{print "Hello---------\n"}{print $1,$2}END{print "ByeBye----------\n"}' a.txt


动作部分可能要点条件或者循环啥的
awk '{if (xx) print $0}'a.txt
awk '{for (oo) print $0}'a.txt
关于匹配
先来一发 ~
awk '{if ($2 ~ /D/ && $3 ~ /[Hh]aoren/) print $0}' a.txt
再来一发 ==
awk '{if ($2 ~ /D/ && $3 == "Haoren") print $0}' a.txt
其实以上两个可以写成,因为动作是默认print的
awk '$2 ~ /D/ && $3 ~ /[Hh]aoren/' a.txt
awk '$2 ~ /D/ && $3 == "Haoren"' a.txt
awk 'BEGIN{IGNORECASE = 1;}{if ($2 ~ /D/ && $3 ~ /[Hh]aoren/) print $0}' a.txt 忽略大小写


sed跟awk一样,也是流编辑器
sed有两个空间
pattern space 模式空间,sed在没有-n(suppress automatic printing of pattern space)参数时都默认打印模式空间。一般每一行记录都只路过模式空间一次。
hold space  暂存空间,中转地方,譬如把模式空间的东东往暂存空间存一下,然后模式空间注入新的东西,一会再去暂存空间取出来。


sed常用的内部操作
n   读取下一行替换当前模式空间的行。
N  读入下一行,追加到模式空间行后面,此时模式空间有两行但只是一坨东西。    
h  把模式空间里的行拷贝到暂存空间。    
H  把模式空间里的行追加到暂存空间。    
g  用暂存空间的内容替换模式空间的行。
G  把暂存空间的内容追加到模式空间的行后。    
X  将暂存空间的内容与模式空间里的内容互换。    
 !  对所选行以外的所有行应用命令。
p  打印当前模式空间的内容。
d   删除模式空间,开始下一个从头开始的操作。
D   删除第一个在模式空间里的换行符前段内容,开始下一个从头开始的操作。
$  匹配最后一行


一些练习
每一行后加一个空行
用一个保持为NULL(里面包括了\n)的东东来追加到模式空间后面
sed 'G' a.txt
在匹配行前加入一个空行
由于在行前加,实际上是先打印NULL再打印行内容,因此需要x交换一个NULL过来。匹配行之后,把模式空间的东西扔到暂存空间(x),于是模式空间当前为NULL,把它打印,然后换回来,模式空间为之前的内容,自动打印模式空间。
sed '/aaa b/{x;p;x;}' a.txt
打印奇数行
有跳行的操作,要跟n/N有关了,不打印就是删除就d吧
sed '{n;d}' d.txt
sed -n '{p;n}' d.txt
sed '0~2d' d.txt
打印偶数行
sed -n '{n;p}' d.txt
sed '1~2d' d.txt
偶数行后加一个空行
sed '{n;G}' d.txt
偶数行置空
sed '{n;g}' d.txt


nohup command &
screen
crontab
expect