读取字符串直到关键字并在UNIX中用另一个字符串替换

时间:2015-02-08 17:19:17

标签: unix awk sed grep

我是UNIX的新手,正在练习shell脚本。我有一个应用程序,我需要字符串搜索和替换。

文件1和文件2中有一些行。我有一个搜索关键字。如果关键字出现在文件1和文件2中,那么文件2中关键字之后的标记应该替换为文件1中关键字之后的字符串。

例如:

文件1:

abc def ghi jkl **unix** is the key
This file contains 3 lines and **unix** is the key

文件2:

This is a sample sentence **unix** in the second file
This is line 2 and **unix** the new line in the second file

关键词是" unix"。在文件文件1中的unix之后的字符串是"是键#34;所以" unix"之后的字符串在文件2中,即#34;在第二个文件中#34;应该替换为"是关键"。所以在字符串读取和替换之后,文件的输出应该看起来像

文件1:

abc def ghi jkl **unix** is the key
This file contains 3 lines and **unix** is the key

文件2:

This is a sample sentence **unix** is the key
This is line 2 and **unix** is the key

我单独使用以下命令

 grep sed awk

但我无法弄清楚如何将搜索和替换结合起来。 任何人都可以告诉我如何做到这一点。感谢任何建议或帮助。

提前致谢

1 个答案:

答案 0 :(得分:0)

对于Unix基本工具,对我来说这在Perl中是最简单的。这将展示基本方法和引用;如果您愿意,可以替换其他工具。

鉴于这些文件:

$ cat /tmp/f1.txt
abc def ghi jkl **unix** is the key
This file contains 3 lines and **unix** is the key

$ cat /tmp/f2.txt
This is a sample sentence **unix** in the second file
This is line 2 and **unix** the new line in the second file

首先,让我们拿到钥匙:

$ key=$(perl -lne 'if (/^.*\*\*unix\*\*(.+)$/) {print $1; exit;} ' /tmp/f1.txt)

注意用$( )围绕对Perl的调用这将执行命令(在本例中为perl one liner)并将输出分配给变量key

$ echo "$key"
 is the key

(注意"周围"$key",以便打印前导空格...)

现在在第二个文件中逐行替换字符串:

$ perl -ple "s/(.*\*\*unix\*\*)(.*)/\1$key/" /tmp/f2.txt
This is a sample sentence **unix** is the key
This is line 2 and **unix** is the key

注意在第二次调用Perl时使用"而不是'。这允许在Bash中使用命令行替换中$key的值。

如果要使用目标键设置Bash变量:

$ tgt='\*\*unix\*\*'
$ key=$(perl -lne "if (/^.*$tgt(.+)/) {print \$1; exit;} " /tmp/f1.txt)
$ perl -ple "s/(.*$tgt)(.*)/\1$key/" /tmp/f2.txt
This is a sample sentence **unix** is the key
This is line 2 and **unix** is the key

(请注意"与更常见的',以便使用$tgt$key的值。)

同样的方法可以与awksed一起使用,但我认为正则表达式更难(至少对我而言)。