其实这篇日志以上面的标题是不准确的。这篇的题目应该是“如何删除除了某个(或某几个)文件(或文件夹)之外的所有文件”。废话不多说,直接上示例吧。(因为这几个文件我不是真的想删除,我们这里用ls代替rm命令,能说明效果就行)

 1[root@gataway opt]# ll
 2总计 68
 3-rw-r--r-- 1 root root    84 04-25 15:41 deltc.sh
 4-rw-r--r-- 1 root root 13121 05-09 15:33 dhcpd.conf
 5-rw-r--r-- 1 root root  6874 06-14 19:08 iptables.sh
 6-rw-r--r-- 1 root root  6572 05-22 14:13 iptables.sh.bak
 7drwxr-xr-x 2 root root  4096 06-13 15:25 iso
 8drwx------ 2 root root 16384 04-19 23:59 lost+found
 9-rw-r--r-- 1 root root  2563 06-06 15:06 tc.sh
10-rw-r--r-- 1 root root  2504 06-06 14:02 tc.sh.120606
11-rw-r--r-- 1 root root  1283 05-03 16:24 test.sh

先来一个有点小白的匹配:

 1[root@gataway opt]# ls |grep -v *.sh
 2#!/bin/bash
 3iptables.sh:
 4iptables.sh:echo "Starting iptables rules..."
 5iptables.sh:
 6iptables.sh:export PATH="/usr/bin:/usr/sbin:/usr/local/sbin:/usr/local/sbin:/bin:/sbin"
 7iptables.sh:iptables -F INPUT
 8iptables.sh:iptables -F FORWARD
 9iptables.sh:iptables -F OUTPUT
10……省略

结果有点像cat的效果了,竟然显示出了.sh文件的内容。而且不是所有的.sh文件的内容。

 1[root@gataway opt]# ls |grep -v "tc.sh|test.sh"
 2deltc.sh
 3dhcpd.conf
 4iptables.sh
 5iptables.sh.bak
 6iso
 7lost+found
 8tc.sh
 9tc.sh.120606
10test.sh

结果是tc.sh和test.sh并未被过滤掉。

1[root@gataway opt]# ls |egrep -v "tc.sh|test.sh"
2dhcpd.conf
3iptables.sh
4iptables.sh.bak
5iso
6lost+found

使用egrep是把tc.sh和test.sh过滤掉了,不过把tc.sh.120606也过滤掉了。注意这里是一个误区,很多给tc.sh和test.sh再增加个单引号,发现和使用ls |egrep -v “tc.sh|test.sh”效果是一样的,所有的都未过滤掉。

再换个高端用法:

1[root@gataway opt]# ls !(tc.sh|test.sh)
2-bash: !: event not found

结果报错了。难道出现这样的情况只能让我们ls |grep -v tc.sh|grep -v test.sh这样不停的去grep -v吗?这个回答肯定是不用的。想按上面的要求进行删除有两种方法:

1、利用find :

 1[root@gataway opt]# find . ! -name tc.sh ! -name test.sh
 2.
 3./lost+found
 4./dhcpd.conf
 5./iso
 6./iso/PCBSD9.0-x64-DVD.iso
 7./iso/PCBSD9.0-x86-DVD.iso
 8./iso/Ylmf_OS_4.0.iso
 9./iso/macos.v10.7.4.dmg
10./iptables.sh
11./deltc.sh
12./tc.sh.120606
13./iptables.sh.bak

这样可以再配合xargs进行rm -rf删除。当然上面的写法和ls |grep -v |grep -v |rm -rf 差不了多少。如果想更简单一些,就要用到shopt了。具体如下:

 1[root@gataway opt]# shopt -s extglob
 2[root@gataway opt]# ls -l !(tc.sh|test.sh)
 3-rw-r--r-- 1 root root    84 04-25 15:41 deltc.sh
 4-rw-r--r-- 1 root root 13121 05-09 15:33 dhcpd.conf
 5-rw-r--r-- 1 root root  6874 06-14 19:08 iptables.sh
 6-rw-r--r-- 1 root root  6572 05-22 14:13 iptables.sh.bak
 7-rw-r--r-- 1 root root  2504 06-06 14:02 tc.sh.120606
 8iso:
 9总计 11801836
10-rw-rw-r-- 1 root root 4179961589 05-27 12:27 macos.v10.7.4.dmg
11-rw-r--r-- 1 root root 3648944128 06-12 19:28 PCBSD9.0-x64-DVD.iso
12-rw-r--r-- 1 root root 3547015168 06-09 14:17 PCBSD9.0-x86-DVD.iso
13-rw-r--r-- 1 root root  697337856 2011-05-30 Ylmf_OS_4.0.iso
14lost+found:
15总计 0

注:后来我发现其实一个grep也可以实现的,ls |grep -v tc.sh|test.sh 。只不与要在|前加一个反斜扛取消转义。

shopt命令和set、export效果是一样的,只有当前终端有效,当退出终端或换个终端后,这个扩展批配就不生效了。当然,如果想使用rm删除,只需要在运行shopt后,再运行rm -rf !(tc.sh|test.sh)就会删除除这两个文件外的所有文件了。

到此,第一问题算是做了完结,第二部分就着重的说明shopt的用法和set的用法了。

注:shopt只能用到bash终端里,其他终端里是不带这个命令的。

1[root@gataway opt]# csh
2[root@gataway /opt]# shopt
3shopt: Command not found.