用bash sed或脚本语言替换文件中的字符串(TCL,perl)

时间:2014-06-10 08:44:34

标签: perl bash shell sed tcl

我有一个C ++源文件列表,它具有以下结构:

// A lot of stuff
#include <current/parser/support/base.hpp>
// ...
#include <current/parser/iterators/begin.hpp>
// ...

我需要替换像

这样的行
#include <current/parser/support/base.hpp>

#include <support_base.hpp>

即,省略current/parser并将分隔符(/)替换为_。 这可能与bash sed或脚本语言有关吗?

编辑:抱歉,忘记提及我想替换

之类的内容
#include <current/parser/*/*/*/*>

任何事情都可以追溯到current/parser之后,任何深度。

4 个答案:

答案 0 :(得分:3)

使用sed:

sed -i -e '/#include <current\/parser\/support\/base\.hpp>/{ s|current/parser/||; s|/|_|; }' -- file1 file2 file3

编辑:

sed -i -e '/#include <current\/parser\/.*>/{ s|current/parser/||; s|/|_|g; }' -- file1 file2 file3

删除currrent/parsers/并将所有/替换为_。示例结果文件:

// A lot of stuff
#include <support_base.hpp>
// ...
#include <iterators_begin.hpp>
// ...

一些细节:

/#include <current\/parser\/.*>/  --  Matcher.
s|current/parser/||               --  Deletes `current/parser/` in matched line.
s|/|_|g                           --  Replaces all `/` with `_` in same line.

答案 1 :(得分:3)

使用Tcl:

# Open the file for reading
set fin [open filein.c r]
# Open the file to write the output
set fout [open fileout.c w]

# Loop through each line
while {[gets $fin line] != -1} {
    # Check for lines beginning with "^#include <current/parser/"
    #
    # ^ matches the beginning of the line
    # ([^>]*) matches the part after "#include <current/parser/" and stores it
    #    in the variable 'match'

    if {[regexp {^#include <current/parser/([^>]*)>} $line - match]} {
        # the edited line is now built using the match from above after replacing
        #    forward slashes with underscores
        set newline "#include <[string map {/ _} $match]>"
    } else {
        set newline $line
    }
    # Put output to the file
    puts $fout $newline
}

# Close all channels
close $fin
close $fout

使用提供的输入输出:

// A lot of stuff
#include <support_base.hpp>
// ...
#include <iterators_begin.hpp>
// ...

Demo on codepad(我编辑了一些代码,因为我无法打开通道来读取/写入文件)

答案 2 :(得分:0)

您可以使用sed-r进行正则表达式尝试:

sed -r 's|#include <current/parser/support/base\.hpp>|#include <support_base.hpp>|g' file

但使用这种方式可能会破坏您的代码。所以要小心:)

答案 3 :(得分:0)

使用perl one-liner

perl -i -pe 's{^#include <\Kcurrent/parser/([^>]*)}{$1 =~ y|/|_|r}e;' file.cpp

或者没有正则表达式功能大于perl 5.10

perl -i -pe 's{(?<=^#include <)current/parser/([^>]*)}{join "_", split "/", $1}e;' file.cpp

说明:

切换

  • -i:编辑文件(如果提供了扩展程序,则进行备份)
  • -p:为输入文件中的每一行创建一个while(<>){...; print}循环。
  • -e:告诉perl在命令行上执行代码。