【问题标题】:how to replace one group of strings in one file with another group from another file如何用另一个文件中的另一组替换一个文件中的一组字符串
【发布时间】:2017-05-18 13:24:26
【问题描述】:

我有两个文件,内容如下

file1

   pattern1something1end1
   pattern1something2end2
   pattern2something3end3
   pattern2something4end4
   pattern3something5end5
   pattern4something6end6

file2

   pattern0something7end7
   pattern1something8end8
   pattern1something9end9
   pattern2something10end10
   pattern2something11end11
   pattern2something12end12
   pattern3something13end13
   pattern4something14end14

现在我希望将 file1 更改为从 pattern2 开始的所有行替换为 file2 中的所有行,这些行在 linux 环境中以相同的 pattern2 开头

所以file1 中的最终内容将如下所示

   pattern1something1end1
   pattern1something2end2
   pattern2something10end10
   pattern2something11end11
   pattern2something12end12
   pattern3something5end5
   pattern4something6end6

文件中的任何模式的行数可以不同,替换应使用行组。

两个文件中只有一组以任何模式开头的行。

我希望最好使用 sed,但这不是一个约束。

如果想为pattern1pattern3 做类似的练习,同样的解决方案也应该起作用

【问题讨论】:

  • 有两个文件行数相同,以pat2开头?如果没有,你如何处理它们
  • @kent 不,以pattern2 开头的行数可以不同。要处理,file1 中的一组行应替换为file2 中存在的一组行
  • 你看过“你如何处理它们”部分吗?
  • @kent 也更新了问题和评论

标签: linux file awk replace sed


【解决方案1】:
awk 'NR==FNR{if(/^pattern2/)a[++i]=$0;next}/^pattern2/{$0=a[++j]}7' f2 f1 

上面的 awk one-liner 会将 file1 中的所有 ^pattern2 行替换为 file2 中的匹配行。

您可以使用awk -v pat="whatever" ...,然后在代码中检查pat 变量,以便使其适用于pattern1, 2, 3,4...

假设file2中的匹配行数>=file1中的数字

根据需求变化更新:

awk 'NR==FNR{if(/^pattern2/)a[++i]=$0;next}
     /^pattern2/{p=1;next}p{for(x in a)print a[x]}7' f2 f1  

测试:

kent$  head f1 f2    
==> f1 <==
pattern1something1end1
pattern1something2end2
pattern2something3end3
pattern2something4end4
pattern3something5end5

==> f2 <==
pattern0something7end7
pattern1something8end8
pattern1something9end9
pattern2something10end10
pattern2something11end11
pattern2something12end12
pattern3something13end13
pattern4something14end14

kent$  awk 'NR==FNR{if(/^pattern2/)a[++i]=$0;next}/^pattern2/{p=1;next}p{for(x in a)print a[x]}7' f2 f1 
pattern1something1end1
pattern1something2end2
pattern2something10end10
pattern2something11end11
pattern2something12end12
pattern3something5end5

【讨论】:

  • 即使匹配的行数file2也是> file1中的数字,它也不起作用
  • 是的!因为您更新了问题。它适用于第一版。
  • 如果我在文件 f1 中添加最后一行,如下所示,它不能正常工作 pattern1something1end1 pattern1something2end2 pattern2something3end3 pattern2something4end4 pattern3something5end5 pattern4something6end6跨度>
  • 请查看我的评论是否有新行添加
【解决方案2】:
 awk 'BEGIN{f=1}
      NR==FNR{if(/^pattern2/){
               if(a==""){a=$0;}else{a=a"\n"$0;}
             }next;}
     /pattern2/&&(f==1)
     {$0=a;f=0;}1' file2 file1

测试结果如下:

[ ~]$ awk 'BEGIN{f=1}NR==FNR{if(/^pattern2/){if(a==""){a=$0;}else{a=a"\n"$0;}}next}/pattern2/&&(f==1){$0=a;f=0}1' file2 file1
pattern1something1end1
pattern1something2end2
pattern2something10end10
pattern2something11end11
pattern2something12end12
pattern2something4end4
pattern3something5end5
[ ~]$

【讨论】:

  • 这一行在你的输出中是额外的 pattern2something4end4
猜你喜欢
  • 2019-03-21
  • 1970-01-01
  • 2018-05-19
  • 2013-06-26
  • 2012-08-18
  • 2015-09-17
  • 1970-01-01
  • 2011-07-01
  • 2020-12-17
相关资源
最近更新 更多