【问题标题】:Insert "xyz" to a line that starts with "abc"将“xyz”插入以“abc”开头的行
【发布时间】:2014-04-04 21:00:14
【问题描述】:

我不习惯将sed 用于任何事情,我不确定这是否可行。

我需要在文本文件中执行以下操作:

  1. 查找以“abc”开头的行
  2. 在所述行的“b”和“c”之间插入“xyz”
  3. 用新行替换原行

一个巨大警告:如果没有以“abc”开头的行,我需要插入一行,并且必须在以“def”开头的行之前插入。

【问题讨论】:

  • 到目前为止您是否尝试过任何代码?

标签: regex shell unix sed


【解决方案1】:

(1) 你的问题的第一部分可以这样写:

sed -i .bak 's/^abc/abxyzc/' input_file

-i .bak 用于就地编辑,并创建扩展名为“.bak”的备份文件)

(2) 第二部分,在另一行之前插入一行(不包括“abc”缺失的情况),可以这样做:

sed -i .bak 's/^def/NEW_LINE\ndef/' input_file

我认为您不能将“if cond do (1) else do (2)”写成单行。为此编写一个简单的脚本...

【讨论】:

    【解决方案2】:

    这可能对你有用(GNU sed):

    sed -r ':a;$!{N;ba};s/(^|\n)(ab)(c)/\1\2xyz\3/;t;s/(^|\n)(def)/\n\1\2/' file
    

    将文件拖入内存。在行首的abc 之间替换xyz。如果执行此替换,则中断进一步处理。否则,在行首的def 之前替换一个换行符。

    【讨论】:

      【解决方案3】:
      awk '
          /^def/ && !inserted {print "abxyzc"; forced = 1}
          /^abc/ && !forced   {sub(/^abc/,"abxyzc"); inserted = 1}
          1
          END {if ((!inserted) && (!forced)) print "abxyzc"}
      ' file > tmp && mv tmp file
      

      如果没有“abc”并且没有“def”,我会在最后打印修改后的“abc”行。您没有指定这种情况。

      【讨论】:

        【解决方案4】:

        sed 会有点复杂。如果您可以使用awk,那么以下应该可以工作。这会对文件进行两次传递。如果它找到/^abc/,它会按照您的要求执行。如果未找到/^abc/,则它会查找/def/ 并在其前一行插入xyz

        awk '
        NR==FNR && /^abc/{ 
            found = 1
            $0 = substr($0,0,2) "xyz" substr($0,3)
            lines[NR] = $0
            next
        }
        NR==FNR {
            lines[NR] = $0 
            next
        }
        !found && /^def/ {
            lines[FNR-1] = lines[FNR-1] "\nabc"
        }
        END {
            for(line=1; line<=FNR; line++) 
                print lines[line]
        }' file{,} > tmp && mv tmp file
        

        【讨论】:

        • 出于好奇,您可以将file file 更改为file{,}
        • @Jotne 谢谢,已修复。
        猜你喜欢
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 2016-07-28
        • 1970-01-01
        • 1970-01-01
        • 2020-08-03
        • 2023-04-10
        • 2014-01-18
        相关资源
        最近更新 更多