shell命令的高级使用之---选择性copy
按文件名选择性copy
【需求】
想将~/1/目录下的大部分文件拷到~/2/目录下,但是这里面有两个.tar结尾的大文件不想拷过去。如果一个一个地将除.tar之外的所有文件和文件夹慢慢手动拷,那么断手也做不完,要是整个夹子完全拷,因为里面有那两个不想要的大文件会占据很长时间。怎样做到一步到位,简单快捷呢?
【原理】
先查看,再grep筛选,而后将筛选的结果作为cp的输入参数。
重点在筛选
【示例】
ls ~/1/ | grep -v ".tar$" | xargs -I {} cp {} ~/2/
【解释】
第一部分:ls ~/1/
查看后用管道传给后面
第二部分: grep -v ".tar$"
“.tar$” 筛选出以.tar结尾的。类似的还可以有:
“^tar” 以tar打头的
"tar[0-9]" tar0~tar9
注意,上述是正则表达式的应用,但不是通配符,*和? 这些通配符在grep命令中不管用
-v是grep的控制选项,-v, --invert-match 选中不匹配的行,即反选的意思。
第三部分: xargs -I {}
xargs命令是将前面管道传入的字符串中的其余空白符(包括空格、换行符、tab制表符)全部用空格取代,使之变为单行
-I 是xargs的控制选项,将xargs的执行结果用某个字符代换,后面的命令可以直接将这个字符当成变量,执行时代入。这里用{}来承接xargs的结果。
【拓展】
如果要同时满足多个条件的筛选,则用 egrep -e "条件1|条件2$" 。 egrep命令就是grep命令的升级版,对正则表达式的支持更强大,-e选项表示后面将是正则表达式,
注意:条件1条件2之间用|符号,|符号周围不能加空格。
如此要实现上面的目的,命令为:ls ~/1/ | egrep -e ".tar$|tar.gz$" -v | xargs -I {} cp {} ~/2/
注意: 这里深绿色部分的-v放后面去了,与上面的grep有点不同。
按文件类别选择性copy
【需求】
想将~/1/目录下除目录之外的普通文件全部拷到~/2/目录下。
【原理】
先查看,因为要按类别区分,所以这里的查看ls已经不能胜任了,得用find命令
再grep筛选,此为重点
而后将筛选的结果作为cp的输入参数。
【示例】
find ~/1/ -type f | egrep -e ".tar$|.tar.gz$" -v | xargs -I {} cp {} ~/2/
【解释】
第一部分:find ~/1/ -type f
查找后用管道传给后面,-type 后面跟的只能是f ,d , c, b , l, s
第二部分: egrep -e "条件1|条件2$" -v
“.tar$” 筛选出以.tar结尾的。类似的还可以有:
“^tar” 以tar打头的
"tar[0-9]" tar0~tar9
注意,上述是正则表达式的应用,但不是通配符,*和? 这些通配符在grep命令中不管用
egrep命令就是grep命令的升级版,对正则表达式的支持更强大,-e选项表示后面将是正则表达式,
注意:条件1条件2之间用|符号,|符号周围不能加空格。
-v是grep的控制选项,-v, --invert-match 选中不匹配的行,即反选的意思。
第三部分: xargs -I {}
xargs命令是将前面管道传入的字符串中的其余空白符(包括空格、换行符、tab制表符)全部用空格取代,使之变为单行
-I 是xargs的控制选项,将xargs的执行结果用某个字符代换,后面的命令可以直接将这个字符当成变量,执行时代入。这里用{}来承接xargs的结果。
按文件大小选择性copy
【需求】
想将~/1/目录下最大的两个文件拷到~/2/目录下。
【原理】
先排序:
ls -lS你会发现按从大到小排序了
ls -lSr是从小到大排序
这里我们不需要其他详细属性,故省去-l,变为 ls -S
挑个数:
ls -S | xargs | awk '{print $1 , $2}'
ls -S出来的是换行的直接用awk是得不到的,所以先要转成一行,再用awk从头到尾按个数取
再copy:
cp `ls -S | xargs | awk '{print $1 , $2}'` ~/2/
将上一步执行的结果用``括起来,命令置换
按文件修改的时间先后选择性copy
【需求】
想将~/1/目录下所有今天修改的文件拷到~/2/目录下。
【原理】
先排序:
ls排序方式:
ls -lt你会发现按从最新到最旧排序
ls -ltr是从最旧到最新排序
这里我们不需要其他详细属性,故省去-l,变为 ls -t
find排序方式:
---(+n)----------|----------(n)----------|----------(-n)---
(n+1)*24H前| (n+1)*24H~n*24H间 |n*24H内
-ctime -n 查找距现在 n*24H 内修改过的文件
-ctime n 查找距现在 n*24H 前, (n+1)*24H 内修改过的文件
-ctime +n 查找距现在 (n+1)*24H 前修改过的文件
[a|c|m]min [最后访问|最后状态修改|最后内容修改]分钟数(n*min)
[a|c|m]time [最后访问|最后状态修改|最后内容修改]天数(n*24H)
命令为 : find ~/1/ -mtime -1
挑个数:
ls -t | xargs | awk '{print $1 , $2}'
ls -S出来的是换行的直接用awk是得不到的,所以先要转成一行,再用awk从头到尾按个数取
若是用find命令查到的则不需要再挑个数
再copy:
cp `ls -t | xargs | awk '{print $1 , $2}'` ~/2/
cp `find ~/1/ -mtime -1` ~/2/
将上一步执行的结果用``括起来,命令置换