如何从我的应用程序目录中删除所有.svn目录


191

我的应用程序中具有导出工具的任务之一是清除.svn应用程序目录树中的所有目录。我正在Linux外壳中寻找一个递归命令,它将遍历整个树并删除.svn文件。

我不使用导出,因为此脚本将用于与SVN不相关的其他文件/目录名称。我尝试了类似的东西:

find . -name .svn | rm -fr

没用...


3
你的命令应该工作,如果你用“xargs的RM -rf”
彼得·范德黑伊登

1
您可能还想修改删除命令“ rm -rfi”,以确保您肯定要删除目录。
bedwyr

不过不要使用xargs ..麻烦目录中带有空格的目录等。请按照以下说明使用find。
约翰·亨特2014年

Answers:


437

试试这个:

find . -name .svn -exec rm -rf '{}' \;

在运行这样的命令之前,我经常喜欢先运行以下命令:

find . -name .svn -exec ls '{}' \;

43
如果目录中可能有空格或此类字符,则可能需要将{}放在单引号中: find . -name .svn -exec rm -rf '{}' \;
mtoloo 2012年

38
此测试对我的find . -name .svn -exec echo {} \;
打击

6
首先运行echo / ls是对此问题的“专业”支持。任何傻瓜都会破坏系统。
约翰·亨特2014年

6
怎么{} \;办?
乔恩·米滕

3
通过运行第二个命令,包括ls,我得到entries prop-base props text-base tmp输出...
Rasoul 2015年

51

您所写的内容将一个用换行符分隔的文件名(和路径)列表发送到rm,但是rm不知道如何处理该输入。只需要命令行参数。

xargs 接受通常由换行符分隔的输入,并将其放置在命令行上,因此添加xargs可以完成您的工作:

find . -name .svn | xargs rm -fr

xargs足够聪明,它只会传递尽可能多的参数rm。因此,如果您有一百万个文件,它可能会运行rm1,000,000 / 65,000次(如果您的shell可以在命令行上接受65,002个参数{65k个文件+ rm 1个--fr 1个)。

正如人们熟练地指出的那样,以下内容也可以工作:

find . -name .svn -exec rm -rf {} \;
find . -depth -name .svn -exec rm -fr {} \;
find . -type d -name .svn -print0|xargs -0 rm -rf

前两种-exec形式都要求rm删除每个文件夹,因此,如果您有1,000,000个文件夹,rm则将被调用1,000,000次。这肯定不理想。较新的实现rm允许您以+指示结束命令,该指示rm将接受尽可能多的参数:

find . -name .svn -exec rm -rf {} +

最后一个find / xargs版本使用print0,它使find生成的输出\0用作终止符而不是换行符。由于POSIX系统只允许\0文件名中包含字符,因此这是确保参数正确传递到rm应用程序或正在执行的应用程序的最安全方法。

此外,还有一个-execdir将从rm文件所在目录执行,而不是从基本目录执行-depth,并且将从深度开始。


31

不需要管道,xargs,exec或其他任何东西:

find . -name .svn -delete

编辑:开个玩笑,显然是在后台-delete调用unlinkat(),因此它的行为类似于unlink或,rmdir并且将拒绝对包含文件的目录进行操作。


54
一个问题,-delete如果目录包含文件,则不会涉及目录。
Xeoncross

2
谓词没有-force或递归标志-delete,因此此答案无用。因此,它返回到|xargs rm -rf,而不是-exec使用其丑陋的占位符和分号:进行输入-exec rm -rf '{}' \;
Tomasz Gandor 2014年

13

对于删除.svn目录,已经提供了许多答案。但我想补充一点,如果您执行导出而不是签出操作,则可以从一开始就避免使用这些目录:

svn export <url>

+1,当它已经内置到svn中时,无需重做。
Powerlord

1
我看到的这种方法唯一的问题是是否要在导出中保留未版本控制的文件。在svn文档中,“将保留所有本地更改,但不会复制不受版本控制的文件。”
raidfive 2010年

@raidfive:通常,我更喜欢将所有相关文件置于版本控制下,甚至使用库也可以使用,以便使该项目开箱即用。此设置中的未版本化文件是编译的二进制文件,这些文件通过构建文件中的目标进行重新制作。但是您是对的,如果您的项目依赖不受版本控制的文件,则导出将无法进行。
Mnementh,2010年

但是...我需要一个更笼统的答案。.svn只是最常见的示例,我在问题中指出。
伊泰Moav -Malimovka

12

如果您不喜欢看到很多

find: `./.svn': No such file or directory

警告,然后使用-depth开关:

find . -depth -name .svn -exec rm -fr {} \;

10

在Windows中,可以使用以下注册表脚本将“删除SVN文件夹”添加到右键单击上下文菜单。在包含这些讨厌文件的任何目录上运行它。

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN]
@="Delete SVN Folders"

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command]
@="cmd.exe /c \"TITLE Removing SVN Folders in %1 && COLOR 9A && FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \""

整洁的把戏。对OP没有帮助,但+1令我印象深刻!
rrhartjr 2013年

这太棒了。谢谢。我知道这很老,但是随便。我仍然喜欢它。
安东尼

9

你差点就吃了。如果要将命令的输出作为参数传递给另一个命令,则需要使用xargs。添加-print0可确保脚本可以处理带有空格的路径:

find . -type d -name .svn -print0|xargs -0 rm -rf

2
为了某种共鸣,最终找到了行之有效的方法。名称.svn | xargs rm -rf但是,您的版本为我提供了指示,谢谢
Itay Moav -Malimovka,2009年


4

一个重要的问题是,当您要使用Shell删除.svn文件夹时,需要使用-depth参数来防止find命令进入刚刚删除的目录并显示错误消息,例如

"find: ./.svn: No such file or directory"

结果,您可以使用如下所示的find命令:

cd [dir_to_delete_svn_folders]
find . -depth -name .svn -exec rm -fr {} \;

这是我一直在寻找的,应该是正确的答案。
luckytaxi


2

另外,如果要导出副本而不修改工作副本,则可以使用rsync:

rsync -a --exclude .svn path/to/working/copy path/to/export

1
或使用svn export / path / to / repository,本质上是一样的。
Kaleb Pederson

作者特别表示,他不想使用svn;也许他的目标环境没有安装svn。
pimlottc
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.