linux shopt和set(一)

其实这篇日志以上面的标题是不准确的。这篇的题目应该是“如何删除除了某个(或某几个)文件(或文件夹)之外的所有文件”。废话不多说,直接上示例吧。(因为这几个文件我不是真的想删除,我们这里用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.

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注