【问题标题】:How do I do a recursive find & replace within an SVN checkout?如何在 SVN 结帐中进行递归查找和替换?
【发布时间】:2011-06-07 12:03:32
【问题描述】:

如何查找和替换每次出现的:

foo

bar

在 /my/test/dir/ 目录树下的每个文本文件中(递归查找/替换)。

但我希望能够在 SVN 结帐中安全地完成此操作,并且不触及 .svn 目录中的任何内容

与此类似,但现在有 SVN 限制:Awk/Sed: How to do a recursive find/replace of a string?

【问题讨论】:

    标签: command-line replace


    【解决方案1】:

    有几种可能:

    使用查找:

    使用 find 创建所有文件的列表,然后将它们通过管道传输到 sed 或您引用的答案中所建议的等价物,非常简单,只需要扫描文件一次。

    您将使用与您引用的问题相同的答案之一,但在 find . 之后添加 -path '*/.svn' -prune -o 以删除 SVN 目录。有关使用 prune 选项和 find 的讨论,请参阅 this question - 尽管请注意他们的模式错误。因此,要打印出所有文件,您可以使用:

    find . -path '*/.svn' -prune -o -type f -print
    

    然后,您可以按照您引用的问题中的建议,将其通过管道传输到 xargs 调用或其他任何进行单独替换的操作。那里有很多关于不同选项的讨论,虽然我更喜欢 John Zwinck's answer 的版本,但我不会在此重复:

    find . -path '*/.svn' -prune -o -type f -exec sed -i 's/foo/bar/g' {} +
    

    使用递归 grep:

    如果您有一个带有 GNU grep 的系统,您也可以使用它来查找文件列表。这可能比 find 效率低,但它确实允许您只在匹配的文件上调用 sed,而且我个人发现语法更容易记住(或从手册页中找出):

    sed -i 's/foo/bar/g' `grep -l -R --exclude-dir='*/.svn' 'foo' .`
    

    -l 选项使 grep 只输出文件名列表,而不是匹配的行。

    使用 GUI 编辑器:

    或者,如果您使用的是 Windows,请按照我的操作 - 获取 NoteTab 编辑器的副本(提供免费版本),并使用它的 search-and-replace-on-disk 命令,该命令忽略隐藏.svn 目录自动运行。

    编辑: 将查找模式更正为 */.svn 而不是 .svn,添加了更多细节和其他一些可能性。但是,这取决于您的平台和 svn 版本:在某些情况下可能需要 .svn 而没有 */,例如在 CentOS 7 上。

    【讨论】:

    • 我想你是说要这样做: find . -path '.svn' -prune -o -type f -print 但这似乎不起作用。
    • 这就是我所说的——而且,你是对的,它不起作用。我想我已经弄清楚了原因,并将进行编辑以更正。
    • 当我在 CentOS 7 上执行递归 grep 时,我仍然得到 .svn 目录。如果我改为输入--exclude-dir='.svn',它们就会消失。
    【解决方案2】:

    这个怎么样?

    grep -i "search_string" `find "*.some_extension"`
    

    这是在具有特定扩展名的文件中查找search_string 的中途解决方案...一旦您知道具有该字符串的文件,就可以通过将其通过管道轻松修改为 sed...。

    【讨论】:

    • 这似乎是一种非常复杂的 grep -R -i "search_string" 处理方式,无论哪种情况,您都需要添加一些内容以排除 SVN 目录。
    • @Brooks:它是一个更便携的版本,因为并非所有 grep 都有递归开关......
    猜你喜欢
    • 2018-03-10
    • 2012-04-28
    • 2011-10-23
    • 2023-03-25
    • 2013-05-26
    • 1970-01-01
    • 2016-08-21
    • 2018-06-25
    • 2012-12-26
    相关资源
    最近更新 更多