删除一个目录和其各级子目录下的.svn文件

本文介绍如何在Linux和Windows系统下删除SVN版本控制系统中的.svn目录,并提供了从服务器端彻底删除SVN版本库中部分文件夹或文件的方法。

来源于: http://www.cnitblog.com/zouzheng/archive/2010/09/26/69197.html

 

 

 

两种方法
[1]用find命令和其action来实现
[2]用rm直接实现
$ cd /tmp/xxx
$ rm -rf  `find . -name .svn`
就可以实现了。

删除SVN目录及从服务器端删除SVN版本库文件方法详解

 

  • 在学习SVN的过程中,你可能会遇到这样的问题,如何删除SVN目录?如何从服务器端彻底删除SVN版本库中部分文件夹或文件夹?本文为你一一解答。
  •  
    1. 技术分享:如何删除SVN备份库
    2. 如何删除SVN及其恢复问题名师指点
    3. 删除SVN版本信息行之有效的办法
    4. SVN基本操作之新手上路
    5. Lniux和Windows下如何删除SVN版本信息?
  •  

    删除SVN目录
    当使用了svn版本控制系统后每个目录下都会有一个.svn目录存在,开发完当交付产品或者上传到服务器时一般要把这些目录删除,这里总结了一下在linux和win下的办法。

    一、在linux下删除SVN

    删除这些目录是很简单的,命令如下
    find.-typed-name".svn"|xargsrm-rf
    或者
    find.-typed-iname".svn"-execrm-rf{}/;
    全部搞定。(http://tech.techweb.com.cn/redirect.php?fid=26&tid=205673&goto=nextnewset)

    二、在windows下删除SVN用以下法子:

    1、在项目平级的目录,执行dos命令:
    xcopyproject_dirproject_dir_1/s/i

    2、或者在项目根目录执行以下dos命令
    for /r . %%a in (.) do @if exist "%%a/.svn" rd/s/q "%%a/.svn"
    其实第二种方法可以用来干很多事的,比如把代码中的.svn替换为任意其他文件名并在硬盘根目录下执行,就可以从硬盘上删除所有的这个文件啦。

    3、加注册表
    JonGalloway提供了一段注册表代码,可以将”DeleteSVNFolders”命名增加到资源管理器的右键上,这样,鼠标点两下就能把选中目录下的所有.svn目录干掉了。Worksjustgreat!
    代码为:
    WindowsRegistryEditorVersion5.00[HKEY_LOCAL_MACHINE/SOFTWARE/Classes/Folder/shell/DeleteSVN]@=”DeleteSVNFolders“[HKEY_LOCAL_MACHINE/SOFTWARE/Classes/Folder/shell/DeleteSVN/command]@=”cmd.exe/c/”TITLERemovingSVNFoldersin%1&&COLOR9A&&FOR/r/”%1/”%%fIN(.svn)DORD/s/q/”%%f/”/”“将这段代码保存为一个.reg文件,双击确认导入注册表即可。


    从服务器端彻底删除SVN版本库中部分文件夹或文件夹
    若要彻底删除SVN版本库某一文件夹或文件,可采取这种方法(举例说明):

    例:假设SVN库路径为E:/svn/project,库中的目录结构为
    QA/Trunk
    Software/Tags/test.exe
    删除Software/Tags/目录下的test.exe文件

    操作步骤为:
    把SVN库dump出来
    使用svndumpfilter过滤掉要删除的文件
    新建一个SVN库
    再将处理好的文件load到新的SVN库里
    具体命令为:
    >svnadmindumpE:/svn/project>aaa.dump
    >typeaaa.dump|svndumpfilterexclude/Software/Tags/test.exe>bbb.dump
    >svnadmincreateE:/svn/project_new
    >svnadminloadE:/svn/project_new<bbb.dump
    然后再将新建的project_new重命名为project,以前的project可以移走,或是另取一个名称.(因为在TRAC中使用的SVN目录是project,用户所使用的SVN目录也是project)

    此方法在SVN库里版本不多的情况下完全可以达到彻底删除SVN版本库某一文件夹或文件的效果,但是如果SVN库里的版本过多,在dump版本的时候会因存储空间不足,而无法dump版本.也就无法操作了.这时须另挂能满足其存储空间的硬盘操作.

    【编辑推荐】

 

<think>我们被要求统计当前目录及其子目录中所有.svn文件(实际上是目录)的大小总。注意.svn一个隐藏目录,通常位于每个工作副本的根目录下。但要注意,每个工作副本只有一个.svn目录,但可能存在多个工作副本(即多个目录下可能有.svn)。 然而,用户要求的是“所有.svn文件”,实际上.svn一个目录,所以我们需要统计每个.svn目录的大小,然后求。 我们可以使用`du`命令来统计目录的大小。但要注意,我们只需要每个.svn目录的总大小,而不是它里面的每个文件。 思路: 1. 使用`find`命令查找当前目录下所有的.svn目录。 2. 对每个找到的.svn目录,使用`du -s`(或`du -sb`)来统计该目录的总大小(以字节为单位)。 3. 将每个.svn目录的大小累加起来,得到总。 但是,需要注意的是,`du -s`会输出每个目录的大小目录名,我们只需要大小数字。而且,可能会有多个.svn目录,我们需要将它们的大小相加。 我们可以使用以下命令组合: ```bash find . -type d -name ".svn" -exec du -sb {} \; | awk '{sum += $1} END {print sum}' ``` 解释: - `find . -type d -name ".svn"`: 从当前目录开始递归查找所有名为".svn"的目录。 - `-exec du -sb {} \;`: 对每个找到的目录执行`du -sb`,`-s`表示总大小,`-b`表示以字节为单位(这样输出时第一个字段就是字节数,后面是目录路径)。 - 然后通过`awk`累加每个目录的大小(第一个字段)并最后输出总。 但是,注意`du -sb`会给出每个目录的确切大小(包括子目录),但每个.svn目录是独立的,所以我们这样累加就是所有.svn目录的总大小。 然而,还有一种情况:同一个.svn目录可能被多次找到?不会,因为每个.svn目录都是独立的,并且find命令会列出每个匹配的目录。 但是,注意:在查找过程中,如果一个目录被包含在另一个.svn目录下(虽然通常不会,因为.svn目录下不会再有另一个.svn),但为了安全,我们这样处理也是没问题的,因为即使嵌套,它们也是独立的目录,都会被统计到。但实际情况下,.svn目录下一般不会有另一个.svn目录。 另外,我们也可以使用`du -s`(不使用-b)那么输出单位是KB,但是这样累加后单位也是KB,但用户可能需要字节或者可读性更好的单位? 我们可以选择使用`du -sb`得到字节,然后累加,最后我们可以通过`awk`将其转换为更易读的单位(如MB、GB)。 但是,用户要求的是“占用磁盘空间”,所以我们可以直接给出字节数,或者为了可读性,我们可以在最后进行单位转换。 然而,我们也可以使用`du -sh`来查看每个目录的可读大小,但是这样我们就无法直接累加(因为每个目录的大小字符串单位不同)。 所以,我们选择先统计字节数,然后转换为人类可读的格式。 另一种方法:我们也可以使用`du -sk`(以KB为单位),这样每个目录的大小都是KB的整数,然后累加,最后再转换。 但是,`du`命令默认的块大小是1024字节(即1KB),所以`-s`(相当于`-sk`)会以1024字节为单位输出大小。我们可以用`-b`(--bytes)来避免块大小的影响。 考虑到可能有非常多的工作副本,我们尽量使用精确字节数。 因此,我们使用上面的命令,但最后用awk将字节数转换为MB或GB。 但是,如果用户只需要总字节数,我们可以直接输出。 另外,我们也可以使用`find`结合`du`然后通过管道传递给`awk`累加,最后用`numfmt`(如果系统支持)来转换单位,或者用awk自己转换。 由于问题中没有要求输出单位,我们可以先给出字节数,然后如果需要,再给出一个可读的格式。 但是,根据引用[4]中关于`du`命令的说明,我们可以使用`-h`选项来输出可读的格式,但是这里我们需要的是总,所以不能直接对每个目录使用`-h`,因为那样无法累加。 所以我们可以这样: 步骤1:计算总字节数 步骤2:将总字节数转换为可读格式 我们可以使用如下命令: 总字节数: total_bytes=$(find . -type d -name ".svn" -exec du -sb {} \; | awk '{sum += $1} END {print sum}') 然后,我们可以用`numfmt`将字节转换为人类可读的格式(如果系统有`numfmt`): echo "总大小(字节): $total_bytes" echo "可读格式: $(echo $total_bytes | numfmt --to=iec)" 或者,如果系统没有`numfmt`,我们可以用awk自己转换,但稍微复杂。 但是,考虑到兼容性,我们可以只输出字节数,或者用awk转换为MB、GB等。 另外,注意:如果当前目录下没有.svn目录,那么find将不会输出任何东西,awk的sum就是0。 我们也可以使用另一个命令:`du`命令有一个`-c`选项,可以输出总计,但是我们需要对每个.svn目录执行`du`,然后得到总计。但是,`du`的`-c`选项是在所有参数执行完后输出总计,而这里我们是通过`find`逐个传递目录,所以无法直接使用。 因此,我们使用上面的管道。 但是,还有一个问题:如果路径中包含空格,`du -sb`的输出会是多个字段吗?不会,`du -sb`的输出格式是:<大小(数字)> <空格> <目录路径>,所以即使路径中有空格,整个路径名也会在第二个字段开始,所以`awk`的`$1`仍然是大小。 所以命令是安全的。 因此,解决方案如下: 在Linux终端中执行: ```bash find . -type d -name ".svn" -exec du -sb {} \; | awk '{sum+=$1} END {print sum}' ``` 这个命令输出的是总字节数。 如果希望得到更友好的显示,可以稍作处理: ```bash total=$(find . -type d -name ".svn" -exec du -sb {} \; | awk '{sum+=$1} END {print sum}') if [ "$total" -eq 0 ]; then echo "没有找到.svn目录" else echo "总大小: $total 字节" # 转换为MB, GB等 echo "即: $(echo $total | awk '{printf "%.2f MB", $1/1024/1024}')" fi ``` 注意:上面的转换中,1MB=1024*1024字节。 但是,如果总大小很大,用GB表示更好,我们可以自动调整单位,但这里我们简单用MB。 另外,如果使用`numfmt`(GNU coreutils的一部分),可以更简单: ```bash total=$(find . -type d -name ".svn" -exec du -sb {} \; | awk '{sum+=$1} END {print sum}') if [ "$total" -eq 0 ]; then echo "没有找到.svn目录" else echo "总大小: $(echo $total | numfmt --to=iec) (字节数: $total)" fi ``` `numfmt --to=iec` 会输出如1M, 1G等,其中iec标准中,1K=1024。 如果没有`numfmt`,我们可以用awk来格式化。 考虑到通用性,我们这里使用awk来转换,但只转换到GB。 另外,我们也可以使用`du -c`来汇总,但需要将找到的目录作为参数传递给du。我们可以用: ```bash find . -type d -name ".svn" -print0 | xargs -0 du -sb | awk '{sum+=$1} END {print sum}' ``` 但是,使用`-exec``xargs`都可以,但如果目录非常多,xargs可以避免参数过长的问题。不过`find`的`-exec`也可以处理,但效率可能稍低。这里我们使用`xargs`的版本可能更高效。 但是,注意:`du -sb`后面可以接多个目录,所以用xargs传递多个目录可以减少调用`du`的次数,提高效率。 因此,改进版: ```bash find . -type d -name ".svn" -print0 | xargs -0 -0 du -sb | awk '{sum += $1} END {print sum}' ``` 但是,如果没有任何.svn目录,xargs会不执行du,那么awk就不会被调用,所以不会有输出。所以我们在脚本中需要处理没有找到的情况。 因此,我们最终的命令行建议: ```bash total=$(find . -type d -name ".svn" -print0 | xargs -0 du -sb 2>/dev/null | awk '{sum += $1} END {if (NR>0) print sum; else print 0}') ``` 然后输出。 或者,我们可以将整个写成一个脚本: ```bash #!/bin/bash total_bytes=$(find . -type d -name ".svn" -print0 | xargs -0 du -sb 2>/dev/null | awk '{sum += $1} END {print sum}') if [ -z "$total_bytes" ]; then total_bytes=0 fi # 或者使用 [ "$total_bytes" == "" ] 来检查,但awk如果没有找到,会输出空 # 所以我们可以这样: if [ -z "$total_bytes" ]; then total_bytes=0 fi # 现在输出 if [ "$total_bytes" -eq 0 ]; then echo "当前目录及其子目录中没有找到任何.svn目录" else # 转换单位 if [ $(command -v numfmt) ]; then human_readable=$(echo $total_bytes | numfmt --to=iec) echo "所有.svn目录总大小: $human_readable (精确字节数: $total_bytes)" else # 自己转换 if [ $total_bytes -ge $((1024**3)) ]; then human_readable=$(echo "scale=2; $total_bytes/1024/1024/1024" | bc) echo "所有.svn目录总大小: ${human_readable} GB (精确字节数: $total_bytes)" elif [ $total_bytes -ge $((1024**2)) ]; then human_readable=$(echo "scale=2; $total_bytes/1024/1024" | bc) echo "所有.svn目录总大小: ${human_readable} MB (精确字节数: $total_bytes)" elif [ $total_bytes -ge 1024 ]; then human_readable=$(echo "scale=2; $total_bytes/1024" | bc) echo "所有.svn目录总大小: ${human_readable} KB (精确字节数: $total_bytes)" else echo "所有.svn目录总大小: $total_bytes 字节" fi fi fi ``` 但是,这个脚本有点长,用户可能只需要一个简单的命令。 因此,我们可以简化:只输出字节数,或者提供一个简单的转换。 考虑到用户要求的是“方法”,我们可以给出一个命令,然后用户可以根据需要转换单位。 所以,我们给出核心命令: **方法1:精确字节数** ```bash find . -type d -name ".svn" -exec du -sb {} \; | awk '{sum+=$1} END {print sum}' ``` **方法2:使用xargs提高效率(适用于大量目录)** ```bash find . -type d -name ".svn" -print0 | xargs -0 du -sb | awk '{sum+=$1} END {print sum}' ``` 然后,用户可以根据输出的字节数自行转换单位。 另外,引用[2]中提到查找文件,我们可以使用`find`命令,我们这里已经使用了。 引用[4]中关于`du`的使用,我们使用了`du -sb`。 因此,我们回答如下: 在Linux系统中,要统计当前目录及其子目录中所有.svn目录的大小总(以字节为单位),可以使用以下命令: ```bash find . -type d -name ".svn" -exec du -sb {} + | awk '{sum += $1} END {print sum}' ``` 命令解释: - `find . -type d -name ".svn"`: 查找当前目录下所有名为`.svn`的目录。 - `-exec du -sb {} +`: 对每个找到的目录执行`du -sb`(`-s`表示汇总大小,`-b`表示以字节为单位),`{}`表示查找到的目录名,`+`表示将多个目录名合并到一个`du`命令中(提高效率)。 - `awk`部分:累加每个目录的大小(`$1`是大小值),最后输出总。 如果希望结果更易读(例如自动转换为MB或GB),可以稍作扩展: ```bash total_bytes=$(find . -type d -name ".svn" -exec du -sb {} + | awk '{sum += $1} END {print sum}') echo "总字节数: $total_bytes" # 转换为MB total_mb=$(echo "scale=2; $total_bytes/1024/1024" | bc) echo "约等于: $total_mb MB" ``` 注意:如果当前目录下没有.svn目录,则输出为0(或空)。另外,`bc`命令用于浮点计算,如果未安装bc,可以用其他方式。 另外,如果目录数量很多,使用`-exec ... +`可能会受命令行参数长度限制(虽然比`\;`好,但仍有极限),这时可以改用`xargs`: ```bash find . -type d -name ".svn" -print0 | xargs -0 du -sb | awk '{sum += $1} END {print sum}' ``` 这个命令利用`-print0``xargs -0`处理文件名中的特殊字符(如空格),并且没有命令行参数数量限制。 因此,推荐使用xargs版本。 最终,我们给出推荐命令: **推荐命令:** ```bash find . -type d -name ".svn" -print0 | xargs -0 du -sb | awk '{sum += $1} END {print sum}' ``` 输出为字节数,用户可以根据需要转换单位。 例如:将字节转换为MB,除以1024*1024。 示例:如果输出是1048576字节,则1048576/(1024*1024)=1MB。 我们也可以参考引用[4]中的`du`使用详解,但这里我们只需要总大小。 注意:这个命令会遍历所有子目录,可能会花费一些时间,特别是当目录结构很深或文件很多时。 另外,如果用户没有权限读取某些目录,可能会报错,我们可以将错误重定向到/dev/null: ```bash find . -type d -name ".svn" -print0 2>/dev/null | xargs -0 du -sb 2>/dev/null | awk '{sum += $1} END {print sum}' ``` 但是,这样会隐藏所有错误,如果用户需要看到权限错误,可以去掉重定向。 因此,根据用户需求,我们给出以上方法。 相关问题: 1. 如何只统计当前目录下(不包括子目录.svn的大小? 2. 如何统计多个指定目录.svn目录的大小? 3. 如何查找并删除所有.svn目录以释放空间? </think> 要统计当前目录及其子目录中所有`.sv`文件(实际上是目录)的大小总,可以使用以下高效可靠的方法: ### 方法 1:使用 `find` + `du` + `awk`(推荐) ```bash find . -type d -name ".svn" -print0 | xargs -0 du -sb | awk '{sum += $1} END {print sum}' ``` **输出结果**:所有`.svn`目录的总字节数(例如 `123456789`) #### 步骤解析: 1. **查找目录** `find . -type d -name ".svn" -print0` - 递归查找当前目录下所有名为`.svn`的**目录** - `-print0` 处理特殊字符(如空格) 2. **计算大小** `xargs -0 du -sb` - `-0` 配合 `-print0` 处理特殊字符 - `du -sb` 显示每个目录的**精确字节数**(`-s` 汇总,`-b` 字节单位) 3. **累加总** `awk '{sum += $1} END {print sum}'` - 累加所有`.svn`目录的大小 - `END` 输出最终总 --- ### 方法 2:转换为人类可读格式(MB/GB) ```bash total_bytes=$(find . -type d -name ".svn" -print0 | xargs -0 du -sb | awk '{sum += $1} END {print sum}') echo "总大小: $(echo "$total_bytes" | numfmt --to=iec) (精确值: $total_bytes 字节)" ``` **输出示例**:`总大小: 1.2G (精确值: 1288490188 字节)` (需安装 `coreutils`,Linux 系统通常自带) #### 手动单位转换(无 `numfmt` 时): ```bash # 计算总字节数 total_bytes=$(find . -type d -name ".svn" -print0 | xargs -0 du -sb | awk '{sum += $1} END {print sum}') # 转换为 MB/GB if [[ $total_bytes -ge 1073741824 ]]; then # 大于 1GB echo "总大小: $(echo "scale=2; $total_bytes/1024/1024/1024" | bc) GB" elif [[ $total_bytes -ge 1048576 ]]; then # 大于 1MB echo "总大小: $(echo "scale=2; $total_bytes/1024/1024" | bc) MB" else echo "总大小: $total_bytes 字节" fi ``` --- ### 关键说明: 1. **为何是目录而非文件** `.svn` 是 SVN 工作副本的**元数据目录**,本质是目录而非文件(引用[1])[^1]。 2. **空间占用根源** 每个`.svn`目录存储完整的版本历史、临时文件等,尤其含大文件或深历史时体积显著(引用[1][^1])。 3. **权限处理** 若遇权限错误,添加重定向: ```bash find . -type d -name ".svn" -print0 2>/dev/null | xargs -0 du -sb 2>/dev/null | ... ``` --- ### 示例验证 ```bash # 创建测试目录 mkdir -p project/{.svn,src} && dd if=/dev/zero of=project/.svn/testfile bs=1M count=10 # 执行统计 find . -type d -name ".svn" -print0 | xargs -0 du -sb | awk '{sum+=$1} END {print sum}' # 输出:10485760 (即 10MB) ``` --- ### 相关问题 1. 如何只统计顶层 `.svn` 目录的大小(不包括嵌套子目录)? 2. 如何查找并删除所有 `.svn` 目录以释放空间? 3. SVN 与 Git 的存储机制在空间占用上有何本质区别? > 引用来源: > [^1]: SVN 工作副本清理与空间分析 > [^4]: Linux `du` 命令详解
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值