我有和这个问题同样的问题如何从文件夹中删除除几个文件夹之外的所有文件/文件夹?多次。这就是我想要自己编写 rmnot 命令脚本的原因。它应该可以获取任意数量的文件,如果需要,甚至可以使用通配符,并删除同一目录中除这些文件之外的所有内容(不是递归的)。典型示例是:
rmnot *tex *bib *png
我的脚本可以运行,但由于我缺乏经验,想以正确的方式学习它,有没有更优雅的方法来编写这个脚本?
#!/bin/zsh
insert="-name . -or -name .."
for i in {1..$#}; do
insert="$insert -or -name ${(P)i}"
done
insert="\( $insert \)"
eval "find -not $insert -exec rm {} \;"
附言:我必须使用 ZSH,因为它有双重替换,${(P)i}
我认为其他任何东西在 bash 中也可以工作。
======优化版本=====
#!/bin/bash
insert="-name . -or -name .."
for i; do
insert="$insert -or -name $i"
done
insert="\( $insert \)"
find -maxdepth 1 -not $insert -delete
答案1
你甚至不需要脚本。如果你使用 bash,你可以打开extglob
并给出否定模式:
$ ls
foo.avi foo.bbl foo.bib foo.log foo.png foo.tex foo.txt foo.wav
$ shopt -s extglob
$ rm !(*tex|*bib|*png)
$ ls
foo.bib foo.png foo.tex
详见man bash
:
If the extglob shell option is enabled using the shopt builtin, several
extended pattern matching operators are recognized. In the following
description, a pattern-list is a list of one or more patterns separated
by a |. Composite patterns may be formed using one or more of the fol‐
lowing sub-patterns:
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
@(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
使用zsh
,等效于:
setopt extended_glob
rm ^(*tex|*bib|*png)
如果您仍想为此编写脚本,只需连接您提供的参数,但不要使用通配符(*
),让脚本添加它们(感谢@Helios 建议一个更简单的版本):
#!/usr/bin/env bash
## Iterate over the arguments
for i
do
## Add them to the pattern to be excluded
pat+="*$i|"
done
## Activate extglob
shopt -s extglob
## Delete non-matching files
rm !(${pat})