其实这篇日志以上面的标题是不准确的。这篇的题目应该是“如何删除除了某个(或某几个)文件(或文件夹)之外的所有文件”。废话不多说,直接上示例吧。(因为这几个文件我不是真的想删除,我们这里用ls代替rm命令,能说明效果就行)
[root@gataway opt]# ll 总计 68 -rw-r--r-- 1 root root 84 04-25 15:41 deltc.sh -rw-r--r-- 1 root root 13121 05-09 15:33 dhcpd.conf -rw-r--r-- 1 root root 6874 06-14 19:08 iptables.sh -rw-r--r-- 1 root root 6572 05-22 14:13 iptables.sh.bak drwxr-xr-x 2 root root 4096 06-13 15:25 iso drwx------ 2 root root 16384 04-19 23:59 lost+found -rw-r--r-- 1 root root 2563 06-06 15:06 tc.sh -rw-r--r-- 1 root root 2504 06-06 14:02 tc.sh.120606 -rw-r--r-- 1 root root 1283 05-03 16:24 test.sh
先来一个有点小白的匹配:
[root@gataway opt]# ls |grep -v *.sh #!/bin/bash iptables.sh: iptables.sh:echo "Starting iptables rules..." iptables.sh: iptables.sh:export PATH="/usr/bin:/usr/sbin:/usr/local/sbin:/usr/local/sbin:/bin:/sbin" iptables.sh:iptables -F INPUT iptables.sh:iptables -F FORWARD iptables.sh:iptables -F OUTPUT ……省略
结果有点像cat的效果了,竟然显示出了.sh文件的内容。而且不是所有的.sh文件的内容。
[root@gataway opt]# ls |grep -v "tc.sh|test.sh" deltc.sh dhcpd.conf iptables.sh iptables.sh.bak iso lost+found tc.sh tc.sh.120606 test.sh
结果是tc.sh和test.sh并未被过滤掉。
[root@gataway opt]# ls |egrep -v "tc.sh|test.sh" dhcpd.conf iptables.sh iptables.sh.bak iso lost+found
使用egrep是把tc.sh和test.sh过滤掉了,不过把tc.sh.120606也过滤掉了。注意这里是一个误区,很多给tc.sh和test.sh再增加个单引号,发现和使用ls |egrep -v “tc.sh|test.sh”效果是一样的,所有的都未过滤掉。
再换个高端用法:
[root@gataway opt]# ls !(tc.sh|test.sh) -bash: !: event not found
结果报错了。难道出现这样的情况只能让我们ls |grep -v tc.sh|grep -v test.sh这样不停的去grep -v吗?这个回答肯定是不用的。想按上面的要求进行删除有两种方法:
1、利用find :
[root@gataway opt]# find . ! -name tc.sh ! -name test.sh . ./lost+found ./dhcpd.conf ./iso ./iso/PCBSD9.0-x64-DVD.iso ./iso/PCBSD9.0-x86-DVD.iso ./iso/Ylmf_OS_4.0.iso ./iso/macos.v10.7.4.dmg ./iptables.sh ./deltc.sh ./tc.sh.120606 ./iptables.sh.bak
这样可以再配合xargs进行rm -rf删除。当然上面的写法和ls |grep -v |grep -v |rm -rf 差不了多少。如果想更简单一些,就要用到shopt了。具体如下:
[root@gataway opt]# shopt -s extglob [root@gataway opt]# ls -l !(tc.sh|test.sh) -rw-r--r-- 1 root root 84 04-25 15:41 deltc.sh -rw-r--r-- 1 root root 13121 05-09 15:33 dhcpd.conf -rw-r--r-- 1 root root 6874 06-14 19:08 iptables.sh -rw-r--r-- 1 root root 6572 05-22 14:13 iptables.sh.bak -rw-r--r-- 1 root root 2504 06-06 14:02 tc.sh.120606 iso: 总计 11801836 -rw-rw-r-- 1 root root 4179961589 05-27 12:27 macos.v10.7.4.dmg -rw-r--r-- 1 root root 3648944128 06-12 19:28 PCBSD9.0-x64-DVD.iso -rw-r--r-- 1 root root 3547015168 06-09 14:17 PCBSD9.0-x86-DVD.iso -rw-r--r-- 1 root root 697337856 2011-05-30 Ylmf_OS_4.0.iso lost+found: 总计 0
注:后来我发现其实一个grep也可以实现的,ls |grep -v tc.sh|test.sh 。只不与要在|前加一个反斜扛取消转义。
shopt命令和set、export效果是一样的,只有当前终端有效,当退出终端或换个终端后,这个扩展批配就不生效了。当然,如果想使用rm删除,只需要在运行shopt后,再运行rm -rf !(tc.sh|test.sh)就会删除除这两个文件外的所有文件了。
到此,第一问题算是做了完结,第二部分就着重的说明shopt的用法和set的用法了。
注:shopt只能用到bash终端里,其他终端里是不带这个命令的。
[root@gataway opt]# csh [root@gataway /opt]# shopt shopt: Command not found.