我的文件夹结构如下所示:
./build
./module/build
./source
我想保留的只是 ./build 及其内容。
该命令find . \! -path ./build -delete
不会删除./build
,而是删除其所有内容。
如何避免这种情况?
答案1
利用您正在使用的 shell (bash):
shopt -s extglob
rm -rfvi ./!(build)
答案2
尝试:
find . \! \( -wholename "./build/*" -o -wholename ./build \) -delete
如果你运行:
rm -rf /tmp/tmp2
mkdir /tmp/tmp2
cd /tmp/tmp2
mkdir -p build module/build source
touch .hidden build/abc build/abc2 source/def module/build/ghi
find . \! \( -wholename "./build/*" -o -wholename ./build \) -delete
find .
你的输出将是:
./build
./build/abc
这比尝试解析 的输出要安全得多ls
,在后者中您必须处理带空格的文件或目录名,甚至更糟糕的是嵌入换行符,find
才能正确处理这些内容。
答案3
扩展吉米的完美答案:
shopt -s extglob
正在将扩展模式匹配加载到 bash 中。从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
following 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
所以:
rm -rfvi ./!(build)
评估为删除除此给定模式之外的所有内容。
答案4
find . \! -path ./build -do_something
不作用于./build
,但会遍历它,以匹配其下的文件。要告诉 find 不要遍历目录,请传递操作-prune
。
find . -path ./build -prune -o . -o -delete
“如果完整路径是,./build
则不要遍历它,否则如果它是当前目录,则不执行任何操作,否则删除该文件。”