【问题标题】:String replacement with awk based on positions in source and target根据源和目标中的位置用 awk 替换字符串
【发布时间】:2018-04-12 19:10:53
【问题描述】:

假设一个多行文本文件file1,其中一些行包含关键字“keyw”。

$ cat file1
foo
bar keyw
baz
keyw qux
quux

进一步假设一个单行文本文件file2 包含与file1 中出现的关键字一样多的字符串。 file2 中的字符串由单个空格分隔。

$ cat file2
string1 string2

我想根据各自的位置将file2 的每个字符串附加到包含关键字的file1 行:

  • file2 中的第一个字符串附加到 file1 中包含关键字的第一行。

  • file2 中的第二个字符串附加到 file1 中包含关键字的第二行。

这是寻找的输出:

$ awk ... file1 file2
foo
bar keyw string1
baz
keyw qux string2
quux

您将使用什么 awk 代码来执行此替换?

【问题讨论】:

  • 你尝试了什么?我相信您之前的一些 awk 问题会引出有趣的代码来帮助解决这个主题!
  • 幸运的是,在您提出问题后的 25 分钟内,您得到了最好的最佳答案,因此能够接受它,而不是等待是否会发布更好的答案。

标签: string bash awk replace position


【解决方案1】:

下面的1给出了上面显示的所需o/p,

使用awk

awk '
     FNR==NR{split($0,strarr);next}
     /keyw/{$0 = $0 OFS strarr[++i]}1
    ' file2 file1

既然你说了,

进一步假设一个单行文本文件 file2 包含尽可能多的 字符串作为 file1 中的关键字出现。 file2 中的字符串是 由单个空格分隔。

说明

  • 使用split($0,strarr);,默认FS单个空格分割记录,元素保存在数组strarr

  • 所以每当记录与file1的正则表达式/keyw/匹配时,我们打印数组元素,变量i将递增,然后转到下一行/记录

  • +1 最后执行默认操作,即打印当前/记录/行,print $0。要了解 awk 的工作原理,请尝试 awk '1' infile,它将打印所有记录/行,而 awk '0' infile 不打印任何内容。零以外的任何数字都是true,它会触发默认行为。

测试结果:

$ cat file1
foo
bar keyw
baz
keyw qux
quux

$ cat file2
string1 string2

$ awk 'FNR==NR{split($0,strarr);next}/keyw/{$0 = $0 OFS strarr[++i]}1' file2 file1
foo
bar keyw string1
baz
keyw qux string2
quux

【讨论】:

    【解决方案2】:

    这就是你所需要的:

    awk 'FNR==NR{split($0,a);next} /keyw/{$0=$0 OFS a[++c]} 1' file2 file1
    

    它可以在任何 awk 中工作,并且不会在非目标行的末尾添加空格。

    【讨论】:

      【解决方案3】:

      如果您的 Input_file 与显示的示例相同,那么请您尝试关注并告诉我这是否对您有帮助。

      awk 'FNR==NR{for(i=1;i<=NF;i++){a[i]=$i}next} {print $0,$0 ~ /keyw/?a[++j]:""}' FIlE2  FIlE1
      

      输出如下。

      foo
      bar keyw string1
      baz
      keyw qux string2
      quux
      

      在这里也添加解释。

      awk '
      FNR==NR{            ##Using FNR==NR condition which will be RUE when first Input_file is getting read. FNR and NR both represents number of lines, only difference between them is FNR value will be RESET on every next file is getting read and NR value will be keep on increasing till all the files are read.
       for(i=1;i<=NF;i++){##Starting a for loop which will run from i variable value 1 to till value of variable NF, where NF is out of the box variable whose value is the value of number of fields on a line.
        a[i]=$i}          ##Creating an array named a whose index is variable i and its value is $i(specific fields value)
        next              ##next will skip all further statements for current line(s).
      }
      {                   ##These statements will be executed when 2nd Input_file is being read.
        print $0,$0 ~ /keyw/?a[++j]:"" ##Printing the value of current line along with that checking of a line has string keyw in it then printing the value of array a whose index is value of j(whose value increments with 1 each time it comes here), else print NULL/nothing.
      }
      ' FIlE2  FIlE1      ##mentioning the Input_file(s) here.
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-06
        • 1970-01-01
        • 1970-01-01
        • 2018-05-02
        • 2016-08-27
        • 1970-01-01
        • 2013-11-04
        相关资源
        最近更新 更多