【问题标题】:Replace in every nth line starting from a certain line从某行开始,每隔 n 行替换一次
【发布时间】:2019-12-13 19:27:19
【问题描述】:

我想使用 sed 从第二行开始每隔三行替换一次。

Input file
A1
A2
A3
A4
A5
A6
A7
.
.
.

Expected output
A1
A2
A3
A4_edit
A5
A6
A7_edit
.
.
.

我知道堆栈上有很多与此相关的解决方案,但对于这个特定问题,我找不到。

我的尝试:

sed '1n;s/$/_edit/;n'

这只会从头开始每隔一行替换一次。

【问题讨论】:

  • 我猜预期输出中的最后一个.实际上应该是._edit?试试sed '4~3 s/$/_edit/' file,见demo。

标签: awk sed replace


【解决方案1】:

如果您对awk 没问题,请尝试关注。

awk -v count="-1" '++count==3{$0=$0"_edit";count=0} 1' Input_file

附加 > temp_file && mv temp_file Input_file 以防您想将输出保存到 Input_file 本身。

解释:

awk -v count="-1" '     ##Starting awk code here and mentioning variable count whose value is -1 here.
++count==3{             ##Checking condition if increment value of count is equal to 3 then do following.
  $0=$0"_edit"          ##Appending _edit to current line value.
  count=0               ##Making value of count as ZERO now.
}                       ##Closing block of condition ++count==3 here.
1                       ##Mentioning 1 will print edited/non-edited lines.
' Input_file            ##Mentioning Input_file name here.

【讨论】:

    【解决方案2】:

    这样的?

    $ seq 10 | sed '1b ; n ; n ; s/$/_edit/'
    1
    2
    3
    4_edit
    5
    6
    7_edit
    8
    9
    10_edit
    

    这分解为一个循环

    • 1b 如果这是输入中的第一行,则开始下一个循环,使用 sed 默认行为打印该行并读取下一行 - 跳过输入中的第一行
    • n 打印当前行并读取下一行 - 跳过三个一组中的第一行
    • n 打印当前行并读取下一行 - 跳过三行中的第二行
    • s/$/_edit/ 在每组三个的第三行替换_edit 的行尾
    • 然后使用默认的sed 行为打印,读取下一行并再次开始循环

    如果您想在开头跳过多行,请将1b 更改为1,5b。

    正如 Wiktor Stribiżew 在 cmets 中指出的那样,作为替代方案,有一个 GNU 范围扩展 first~step,它允许我们写

    sed '4~3s/$/_edit/'
    

    这意味着从第 4 行开始每隔三行替换一次。

    【讨论】:

    • @kashiff007 我希望这是足够的解释。我还在原始问题的 cmets 中包含了 Wiktor Stribiżew 建议的步进范围语法。
    【解决方案3】:

    另一个awk

    awk 'NR>3&&NR%3==1{$0=$0"_edit"}1' file
    A1
    A2
    A3
    A4_edit
    A5
    A6
    A7_edit
    A8
    A9
    A10_edit
    A11
    A12
    A13_edit
    

    NR>3 测试行是否大于 3
    NR%3==1 和每隔三行
    {$0=$0"_edit"} 编辑行
    1 打印所有内容

    【讨论】:

      【解决方案4】:

      您可以使用 seds ~ 步进运算符。

      sed '4~3s|$|_edit|'
      

      ~ 是 GNU sed 的一个特性,因此它可以在大多数(所有?)Linux 发行版中使用。但要在 macOS(BSD sed 附带)上使用它,您必须安装 GNU sed 才能获得此功能:brew install gnu-sed。

      【讨论】:

      • 也许sed '4~3s/$/_edit/' file 可能是一个更好的例子,考虑到解决方案的目标受众,因为替换命令的替代分隔符(没有好处)可能会使初学者感到困惑。
      猜你喜欢
      • 2019-10-07
      • 2017-09-11
      • 2016-02-06
      • 2015-09-29
      • 1970-01-01
      • 1970-01-01
      • 2013-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多