【问题标题】:Linux: how to replace all instances of a string with another in all files of a single typeLinux:如何在单一类型的所有文件中用另一个字符串替换所有实例
【发布时间】:2012-09-22 15:31:55
【问题描述】:

例如,我想用文件夹中所有 .txt 文件中包含的“321”替换所有“123”实例(递归)。 我想过这样做

sed -i 's/123/321/g' | find . -name \*.txt

但在搞砸我所有的文件之前,我想问问它是否可以工作。

【问题讨论】:

    标签: linux replace sed find


    【解决方案1】:

    你有 sed 和 find 从后到前。使用 GNU sed 和 -i 选项,您可以使用:

    find . -name '*.txt' -type f -exec sed -i s/123/321/g {} +
    

    find 查找扩展名为 .txt 的文件并在它们的组上运行 sed -i 命令(最后是 +;它是 POSIX 2008 中的标准,但并非所有版本的 find 都必须支持它)。在此示例替换中,不存在误解 s/123/321/g 命令的危险,因此我没有将其括在引号中。但是,为了简单和一般安全,最好尽可能将 sed 脚本用单引号括起来。

    你也可以使用xargs(同样使用GNU扩展-print0到find和-0和-r到xargs):

    find . -name '*.txt' -type f -print0 | xargs -0 -r sed -i 's/123/321/g'
    

    -r 的意思是“如果没有参数就不要运行”(所以find 什么也找不到)。 -print0 和 -0 协同工作,生成以 C 空字节 '\0' 而不是换行符结尾的文件名,并避免对包含换行符、空格等的文件名的误解。

    请注意,在对真实数据运行脚本之前,您可以并且应该对其进行测试。创建一个虚拟目录(我通常称之为junk),将一些示例文件复制到垃圾目录中,将目录更改为垃圾目录,然后在这些文件上测试您的脚本。由于它们是副本,因此如果出现问题,也不会造成任何伤害。之后您可以简单地删除目录中的所有内容:rm -fr junk 永远不会让您感到痛苦。

    【讨论】:

    • 谢谢。稍加调整就可以了:您忘记了引号 find 。 -name '*.txt' -type f -exec sed -i 's/123/321/g {}' +
    • 有趣;如果有人问我,我会说你显示的报价会破坏它,而不是修复它。但我有什么资格与经验证据争论......
    猜你喜欢
    • 2020-12-17
    • 1970-01-01
    • 2018-07-05
    • 2015-06-08
    • 2019-04-22
    • 1970-01-01
    • 2020-08-27
    • 1970-01-01
    • 2021-08-16
    相关资源
    最近更新 更多