在linux上安全搜索和替换

时间:2014-05-07 07:52:53

标签: regex search replace sed grep

我们认为我的文件位于不同的子文件夹中,我想在这些文件中搜索,测试和替换内容。

我想分三步完成:

  1. 搜索特定模式(有或没有正则表达式)
  2. 测试用某些东西替换它(有或没有正则表达式)
  3. 仅将更改应用于相关文件
  4. 我目前的解决方案是在.bashrc中定义一些别名,以便轻松使用grepsed

    alias findsrc='find . -name "*.[ch]" -or -name "*.asm" -or -name "*.inc"'
    alias grepsrc='findsrc | xargs grep -n --color '
    alias sedsrc='findsrc | xargs sed '
    

    然后我用

    1. grepsrc <pattern>搜索我的模式
    2. (尚无解决方案)
    3. sedsrc -i 's/<pattern>/replace/g'
    4. 不幸的是,这个解决方案并不能让我满意。第一个问题是sed触摸所有文件,即使没有任何变化。然后,使用别名的需要对我来说看起来不太干净。

      理想情况下,我希望有一个与此类似的工作流程:

      注册新的上下文:

      $ fetch register 'mysrcs' --recurse *.h *.c *.asm *.inc 
      

      上下文列表:

      $ fetch context
       1. mysrcs --recurse *.h *.c *.asm *.inc
       Extracted from ~/.fetchrc
      

      找到一些东西:

      $ fetch files mysrcs /0x[a-f0-9]{3}/
      ./foo.c:235     Yeah 0x245
      ./bar.h:2       Oh yeah 0x2ac hex
      

      测试替代品:

      $ fetch test mysrcs /0x[a-f0-9]{3}/0xabc/
      ./foo.c:235     Yeah 0xabc
      ./bar.h:2       Oh yeah 0xabc hex 
      

      申请替换:

      $ fetch subst --backup mysrcs /0x[a-f0-9]{3}/0xabc/
      ./foo.c:235     Yeah 0xabc
      ./bar.h:2       Oh yeah 0xabc hex 
      
      Backup number: 242
      

      出现错误时恢复:

      $ fetch restore 242
      

      这种工具对我来说非常标准。每个人都需要搜索和替换。我可以使用哪种替代方案在Linux中是标准的?

4 个答案:

答案 0 :(得分:2)

#!/bin/ksh

# Call the batch with the 2 (search than replace) pattern value as argument

# assuming  the 2 pattern are "sed" compliant regex
SearchStr="$1"
ReplaceStr="$2"

# Assuming it start the search from current folder and take any file
# if more filter needed, use a find before with a pipe
grep -l -r "$SearchStr" . | while read ThisFile
 do
    sed -i -e "s/${SearchStr}/${ReplaceStr}/g" ${ThisFile}
 done

应该是适应您需求的基本脚本

答案 1 :(得分:2)

我经常要执行这样的维护任务。我混合使用findgrepsedawk

而不是别名,我使用函数。

例如:

# i. and ii.
function grepsrc {
    find . -name "*.[ch]" -or -name "*.asm" -or -name "*.inc" -exec grep -Hn "$1"
}

# iii.
function sedsrc {
    grepsrc "$1" | awk -F: '{print $1}' | uniq | while read f; do
        sed -i s/"$1"/"$2"/g $f
    done
}

用法示例:

sedsrc "foo[bB]ar*" "polop"

答案 2 :(得分:1)

for F in $(grep -Rl <pattern>) ; do sed 's/search/replace/' "$F" | sponge "$F" ; done
    带有grep参数的
  • -l仅列出与
  • 匹配的文件
  • 然后我们使用迭代器来运行那些通过sed
  • 匹配的文件
  • 我们使用sponge包中的moreutils程序将处理后的流写回同一个文件

这很简单,不需要额外的shell函数或复杂的脚本。

如果你想让它安全......请将文件夹检入Git存储库。那是什么版本控制。

答案 3 :(得分:0)

是的,有一个工具正在寻找您正在寻找的工具。这是Git。如果专业工具可以为您完成这项工作,您为什么要管理文件备份?

您将请求拆分为3个子请求:

  • 如何快速搜索我的文件子集?
  • 如何临时应用替换,然后回到原始状态?
  • 如何替换为您的文件子集?

我们首先需要在您的工作区中完成一些工作。您需要初始化Git存储库,然后将所有文件添加到此存储库中:

$ cd my_project
$ git init
$ git add **/*.h **/*.c **/*.inc 
$ git commit -m "My initial state"

现在,您可以使用以下命令快速获取文件列表:

$ git ls-files

要进行替换,您可以使用sedperlawk。这是使用sed

的示例
$ git ls-files | xargs sed -i -e 's/search/replace/'

如果您对此更改不满意,可以随时回滚:

$ git checkout HEAD

这使您可以随时测试您的更改和后退。

现在,我们还没有简化命令。所以我建议为你的Git配置文件添加一个别名,通常位于~/.gitconfig。加上这个:

[alias]
sed = ! git grep -z --full-name -l '.' | xargs -0 sed -i -e

所以现在你可以输入:

$ git sed s/a/b/

这很神奇......