2015-03-13 34 views
0

我正在寻找一种方法,用awk直接在文件中替换使用awk找到的记录。因此Bash查找并替换awk文件中的记录

cat file 

    public function method1() 
    { 
     return 1; 
    } 

    /** 
    * old comment 
    */ 
    public function oldMethod() 
    { 
     return 'old'; 
    } 

    public function method3() 
    { 
     return 3; 
    } 

AWK返回

awk 'BEGIN{RS="\n\n"; IGNORECASE=1} /oldMethod/ {print $0}' file 
    /** 
     * old comment 
     */ 
    public function oldMethod() 
    { 
     return 'old'; 
    } 

UPDATE预期的输出例如为:

cat file 

    public function method1() 
    { 
     return 1; 
    } 

    /** 
    * new comment 
    */ 
    public function newMethod() 
    { 
     /*Do some fancy stuff here*/ 
     return 'another output'; 
    } 

    public function method3() 
    { 
     return 3; 
    } 

现在我要替换此方法包含在一个变量的方法。 我不知道如何实现这一点。 有没有人一个好主意?

问候 nTOXIC

+0

您的预期输出是什么? – 2015-03-13 10:29:12

+0

在更换oldMethod() – nTOXIC 2015-03-13 10:32:28

+0

后更新了我的请求,并更新了示例输出以更清晰地说明这不仅仅是替换单词部分的问题。 – nTOXIC 2015-03-13 11:12:24

回答

1

所有你需要的是:

awk -v new="$var" -v RS= -v ORS='\n\n' '/oldMethod/{$0=new}1' file 

参见:

var=$(cat << '_EOF_' 
/** 
* new comment 
*/ 
public function newMethod() 
{ 
    /*Do some fancy stuff here*/ 
    return 'another output'; 
} 
_EOF_ 
) 

$ awk -v new="$var" -v RS= -v ORS='\n\n' '/oldMethod/{$0=new}1' file 
public function method1() 
{ 
    return 1; 
} 

/** 
* new comment 
*/ 
public function newMethod() 
{ 
    /*Do some fancy stuff here*/ 
    return 'another output'; 
} 

public function method3() 
{ 
    return 3; 
} 

只要改变/oldMethod/到然而很多你想要搜索的,如果它需要比这更旧的纪录。如果要指定一个变量也只是改变了命令行:

awk -v new="$var" -v old="oldMethod" -v RS= -v ORS='\n\n' '$0~old{$0=new}1' file 

对于@ anishane的答案比较,如果你在一个文件,而不是一个变量有“新”记录你会需要是:

awk -v RS= -v ORS='\n\n' 'NR==FNR{new=$0;next} /oldMethod/{$0=new}1' newfile.c input.c 
2
$ cat input.c 

public function method1() 
{ 
    return 1; 
} 

/** 
* old comment 
*/ 
public function oldMethod() 
{ 
    return 'old'; 
} 

public function method3() 
{ 
    return 3; 
} 

-

$ cat newfile.c 
/** 
* new comment 
*/ 
public function newMethod() 
{ 
    /*Do some fancy stuff here*/ 
    return 'another output'; 
} 

-

$ awk -v RS= -v ORS=$'\n' 'NR==FNR{a=a $0 "\n"; next;}/oldMethod/{print ORS a; next;}1' newfile.c input.c 

public function method1() 
{ 
    return 1; 
} 

/** 
* new comment 
*/ 
public function newMethod() 
{ 
    /*Do some fancy stuff here*/ 
    return 'another output'; 
} 

public function method3() 
{ 
    return 3; 
} 

说明:

  1. -v RS=将RS设置为空字符串:表示由空行分隔记录。
  2. -v ORS=$'\n'输出记录分隔符。
  3. 'NR==FNR{a=a $0 "\n"; next;}'捕获名为a的变量中的第一个文件。移至下一条记录。
  4. '/oldMethod/{print ORS a; next;}1'对于记录匹配/模式/,打印a。其他打印记录。
  5. newfile.c是第一个文件。 input.c是参数列表中的第二个文件。
+0

你做了我的一天。谢谢:) – nTOXIC 2015-03-13 11:57:04

+0

为什么你在默认值时设置ORS = $'\ n''?为什么你有时在文本中使用明确的''\ n“',在其他时候'ORS'?当整个'newfile.c'将被读作一条记录时,你为什么要追加'a'('a = a $ 0“\ n”')?这是非常令人困惑的代码...我在答案的最后添加了一个更简单的版本。 – 2015-03-13 21:51:02

+0

@EdMorton:''当整个newfile.c将被读作一条记录时,你为什么要追加到(a = a $ 0“\ n”):'在这种情况下是真的。不一定总是如此。 OP可能希望扩展newfile.c以包含更多功能...... – anishsane 2015-03-16 03:28:10