Bash: Inserting one file's content into another file after the pattern

后端 未结 5 1477
一向
一向 2020-12-30 07:16

I\'m trying to write a bash script, which will do the following:

  1. reads the content from the first file (as a first argument)
  2. reads the content from th
相关标签:
5条回答
  • 2020-12-30 07:48

    I use sed like this and it worked as a charm

    sed -i -e '/pattern/r filetoinsert' filetobeinserted

    What it does is insert the 'filetoinsert' into 'filetobeinserted' after the line with the specified pattern

    Take care to choose a unique pattern, not sure how it will work with a duplicate patterns, I assume it will do it just of the first one

    0 讨论(0)
  • 2020-12-30 07:56

    You need spaces around the =~ operator. Compare:

    [[ foo=~bar ]]
    [[ foo =~ bar ]]
    

    This is because the first expression essentially evaluates as "Is this string empty?"

    Also, the OP code uses small tilde rather than tilde.

    Even so, you can easily get rid of the inner loop. Just replace the whole while read -r line2 bit with cat -- "$second_filename".

    Your last echo $line is only correct if the file does not end in a newline character (standard with *nix tools). Instead, you should use while read -r line || [[ $line ~= '' ]]. This works with or without newline at the end.

    Also, Use More Quotes™.

    0 讨论(0)
  • 2020-12-30 07:56

    Using awk works as well.

    To insert before the ###marker### line :

    // for each <line> of second_file.txt :
    //   if <line> matches regexp ###marker###, outputs first_file.txt.
    //   **without any condition :** print <line>
    awk '/###marker###/ { system ( "cat first_file.txt" ) } \
         { print; } \' second_file.txt
    

    To insert after the ###marker###line :

    // for each <line> of second_file.txt :
    //   **without any condition :** print <line>
    //   if <line> matches regexp ###marker###, outputs first_file.txt.
    awk '{ print; } \
         /###marker###/ { system ( "cat first_file.txt" ) } \' second_file.txt
    

    To replace the ###marker### line :

    // for each <line> of second_file.txt :
    //   if <line> matches regexp ###marker###, outputs first_file.txt.
    //   **else**, print <line>
    awk '/###marker###/ { system ( "cat first_file.txt" ) } \
         !/###marker###/ { print; }' second_file.txt
    

    If you want to do in-place replacement, use a temp file for being sure the pipe doesn't start before awk has read the entire file; add :

    > second_file.txt.new
    mv second_file.txt{.new,}
    // (like "mv second_file.txt.new second_file.txt", but shorter to type !)
    

    If you want replacement inside of the line, (replacing just the pattern and keeping the rest of the line), a similar solution should be achievable with sed instead of awk.

    0 讨论(0)
  • 2020-12-30 08:00

    sed can do that without loops. Use its r command:

    sed -e '/pattern/rFILE1' FILE2
    

    Test session:

    $ cd -- "$(mktemp -d)" 
    $ printf '%s\n' 'nuts' 'bolts' > first_file.txt
    $ printf '%s\n' 'foo' 'bar' 'baz' > second_file.txt
    $ sed -e '/bar/r./first_file.txt' second_file.txt
    foo
    bar
    nuts
    bolts
    baz
    
    0 讨论(0)
  • 2020-12-30 08:05

    This should work:

    perl -lne 'BEGIN{open(A,"first_file.txt");@f=<A>;}print;if(/2222/){print @f}' second_file.txt
    

    Tested:

    > cat temp
    111111
    1111
    11
    1
    > cat temp2
    122221
    2222
    22
    2
    > perl -lne 'BEGIN{open(A,"temp");@f=<A>;}print;if(/2222/){print @f}' temp2
    122221
    111111
    1111
    11
    1
    
    2222
    111111
    1111
    11
    1
    
    22
    2
    > 
    
    0 讨论(0)
提交回复
热议问题