【问题标题】:Insert text before a certain line using Bash使用 Bash 在某一行之前插入文本
【发布时间】:2012-09-03 13:24:34
【问题描述】:

如何将一组行(大约 5 行)插入到文件中第一个位置找到字符串?

例如:

BestAnimals.txt

dog
cat
dolphin
cat

$ "在猫之前将长颈鹿插入 BestAnimals.txt" > NewBestAnimals.txt

NewBestAnimals.txt

dog
giraffe 
cat
dolphin
cat

【问题讨论】:

    标签: bash shell


    【解决方案1】:

    如果使用 gnu sed:

    $ cat animals
    dog
    cat
    dolphin
    cat
    
    $ sed  "/cat/ { N; s/cat\n/giraffe\n&/ }" animals
    dog
    giraffe
    cat
    dolphin
    cat
    
    1. 用 (/cat/) 匹配一行
    2. 在下一行继续 (N)
    3. 用插入和匹配的字符串替换匹配的模式,其中&代表匹配的字符串。

    【讨论】:

    • 是的,应该补充一下。已更新。
    • 先有nyan cat这一行就有问题,比如
    • 是的,但这不是问题的一部分 ;-) 从最简单的解决方案开始,也就是 KISS,然后在出现问题时从那里开始
    • 这是真的!我只是向您提出了解决此问题的方法。我还发现了另一个问题:cat 的第一次出现不能在最后一行。不知道如何解决这个问题!
    • 它们都是有效的解决方案,但你首先回答了,所以被接受了。
    【解决方案2】:
    awk -v insert=giraffe -v before=cat '
      $1 == before && ! inserted {
        print insert
        inserted++
      }
      {print}
    ' BestAnimals.txt > NewBestAnimals.txt
    

    【讨论】:

    • 定义两个变量insert,取值“giraffe”和变量before。对于每一行:如果第一个 WS 分隔标记,例如"dog" 匹配变量 before 的内容,并且未定义变量插入的打印变量 insert 即“长颈鹿。增加插入变量以便后续匹配不会产生打印。最后,所有行的默认操作是 @ 987654326@ 即输出输入行。@glennjackman 先生一如既往的漂亮解决方案:-)
    【解决方案3】:

    如果你知道(或以某种方式找出)这条线:

    sed -n '/cat/=' BestAnimals.txt
    

    你可以使用 sed:

    sed -i '2i giraffe' BestAnimals.txt
    

    【讨论】:

    • 如何处理多个单词?我得到 sed: -e expression #1, char 4: extra characters after command
    【解决方案4】:

    一个 awk 解决方案:

    awk '/cat/ && c == 0 {c = 1; print "giraffe"}; {print}' \
         BestAnimals.txt
    

    如果您要插入的动物在“MyOtherBestAnimals.txt”中,您也可以这样做

    awk '/cat/ && c == 0 {c = 1; system("cat MyOtherBestAnimals.txt") }; {print} ' \
         BestAnimals.txt
    

    这个答案基本上可以分解如下,因为;分隔了awk条件-动作对:

    • /cat/ && c == 0 { c = 1; ... } 在包含 cat 的第一行将 c 设置为 1。放在... 的命令随后会被执行,但只执行一次,因为c 现在是1。
    • {print} 是无条件的操作打印:打印任何输入行。这是在上述条件-动作对之后完成的。

    根据... 的实际内容,打印长颈鹿,或将“MyOtherBestAnimals.txt”的内容发送到标准输出,然后打印包含“cat”的第一行。

    编辑

    分析了@glenn jackman的解决方案,看来这个解决方案还是可以改进的:当使用输入文件时

    nyan cat
    cat
    

    数据附加在nyan cat 之前,而不是在等于cat 的行之前。解决方案是请求整行等于cat

    awk '$0 == "cat" && c == 0 {c = 1; print "giraffe"}; {print}' \
         BestAnimals.txt
    

    用于插入单行和

    awk '$0 == "cat" && c == 0 {c = 1; system("cat MyOtherBestAnimals.txt") }; {print} ' \
         BestAnimals.txt
    

    用于插入文件

    【讨论】:

    • OP 想要插入 before cat 而不是 after dog
    【解决方案5】:

    我愿意:

    1. 使用grep查找第一个匹配的行号
    2. 使用head 获取导致匹配的文本
    3. 使用cat 插入新内容
    4. 使用tail获取匹配后的行数

    它既不快速、高效也不优雅。但这很简单,如果文件不是很大和/或您需要每秒执行多次,那应该没问题。

    【讨论】:

    • 我只是想自动化一项无聊的任务,因为我是一名计算机科学家,所以速度并不重要,大约有 500 个文件!
    猜你喜欢
    • 2015-11-07
    • 2018-05-13
    • 2014-07-04
    • 1970-01-01
    • 1970-01-01
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    • 2012-11-17
    相关资源
    最近更新 更多