Insert text before a certain line using Bash

前端 未结 5 1436
时光说笑
时光说笑 2020-12-17 04:24

How can I insert a set of lines (about 5) into a file at the first place a string is found?

For example:

BestAnimals.txt

dog         


        
相关标签:
5条回答
  • 2020-12-17 04:29
    awk -v insert=giraffe -v before=cat '
      $1 == before && ! inserted {
        print insert
        inserted++
      }
      {print}
    ' BestAnimals.txt > NewBestAnimals.txt
    
    0 讨论(0)
  • 2020-12-17 04:40

    An awk solution:

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

    If the animals you want to insert are in "MyOtherBestAnimals.txt" you can also do

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

    This answer can basically be broken down as follows, because ; separates the awk condition-action pairs:

    • /cat/ && c == 0 { c = 1; ... } sets c to 1 at the first row containing cat. The commands put at the ... are then executed, but only once, because c is 1 now.
    • {print} is the action print with no condition: prints any input line. This is done after the above condition-action pair.

    Depending on what is actually at the ..., giraffe is printed, or the contents of "MyOtherBestAnimals.txt" is sent to the standard output, before printing the first line containing "cat".

    Edit

    After analysis of @glenn jackman's solution, it seems this solution can still be improved: when using input file

    nyan cat
    cat
    

    the data is appended before nyan cat and not before the line equal to cat. The solution is then to request the full line to be equal to cat:

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

    for the insertion of a single line and

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

    for the insertion of a file

    0 讨论(0)
  • 2020-12-17 04:43

    I would:

    1. Use grep to find the line number of the first match
    2. Use head to get the text leading up to the match
    3. Insert the new content using cat
    4. Use tail to get the lines after the match

    It's neither quick, efficient nor elegant. But it's pretty straight-forward, and if the file isn't gigantic and/or you need to do this many times a second, it should be fine.

    0 讨论(0)
  • 2020-12-17 04:45

    If using gnu sed:

    $ cat animals
    dog
    cat
    dolphin
    cat
    
    $ sed  "/cat/ { N; s/cat\n/giraffe\n&/ }" animals
    dog
    giraffe
    cat
    dolphin
    cat
    
    1. match a line with (/cat/)
    2. continue on next line (N)
    3. substitute the matched pattern with the insertion and the matched string, where & represent the matched string.
    0 讨论(0)
  • 2020-12-17 04:49

    If you know (or somehow find out) the line:

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

    You can use sed:

    sed -i '2i giraffe' BestAnimals.txt
    
    0 讨论(0)
提交回复
热议问题