dice2011
dice2011

Reputation: 1037

Bash - Insert string with newlines after the information, that looks like block of text

I have a string ($pastestring) with newlines, that I declared like this

pastestring=$'\n##### Branch FREEZE enable/disable:\n Freeze: enable '

I have a document (with path $file). The document is rather big, but my task is: when i find a text, that is simular to this.

######## Branch Owner #########
Owner: James Jones
Mail: [email protected]
###############################

(so the amount of "#" symbols can be different, Owner and Mail parameters can be different too)

I need to make a new line and paste information that I have inside of document, so it should look like

######## Branch Owner #########
Owner: James Jones
Mail: [email protected]
###############################

##### Branch FREEZE enable/disable
Freeze: enable

First of all, I don't really know, how to make a pattern that will help me to find a text, that looks like the text above (I don't know, how to pattern with newlines inside).

If I am trying to paste my test like this (in this case I look only at "###############################" symbols)

sed -i "/###############################/a "${pastestring}"" $file

I get a lot of mistakes because of newlines and special symbols inside of string.

sed: -e expression #1, char 35: expected \ after `a', `c' or `i'

Any help to fixing this appreciated!

UPDATE @Inian The content of the $file looks like this

######## Branch Owner #########
Owner: Jones Jane
Mail: [email protected]
###############################

##### Branch RELEASE enable/disable
Release: disable

##### Branch configuration enable/disable
Release: enable

##### Branch output enable/disable
Release: enable

I need to put my string in file after

######## Branch Owner #########
Owner: Jones Jane
Mail: [email protected]
###############################

It can be identified, by the way, that it looks

##### (some symbols #)
Owner: (some text)
Mail: (some text)
##### (some symbols #)

And I don't really know, how to make a pattern for it.

The result should be

######## Branch Owner #########
Owner: Jones Jane
Mail: [email protected]
###############################

##### Branch FREEZE enable/disable
Freeze: disable

##### Branch RELEASE enable/disable
Release: disable

##### Branch configuration enable/disable
Release: enable

##### Branch output enable/disable
Release: enable

UPDATE @Inian, could you take a look again? I have just found out another problem here. Your scripts pastes the text twice. The content of file is

######## Branch Owner #########
Owner: Jones Jane
Mail: [email protected]
###############################

##### Branch RELEASE enable/disable
Release: disable

##### Branch configuration enable/disable
Release: enable

##### Branch output enable/disable
Release: enable

##### Branch Contributors #####
user1
user2
user3
user4
yooseftal
markout
(and other users)
###############################


#### Code Review enable/disable
CR: enable

So the script pastes text also after the Branch Contributors section

Upvotes: 1

Views: 143

Answers (2)

Inian
Inian

Reputation: 85530

If you don't mind using Awk for this, you can do it as below,

pastestring=$'\n##### Branch FREEZE enable/disable:\nFreeze: enable '
awk -v string="${pastestring}" '/Branch Owner/{print; flag=1; next}$0 ~ "^[#]*$" && flag && NF{print; print string; flag=0; next}1' file "$file"

which produces an output as below,

######## Branch Owner #########
Owner: James Jones
Mail: [email protected]
###############################

##### Branch FREEZE enable/disable:
Freeze: enable

The key to the solution is to identify the regex only for the line starting with # which can be done by

$0 ~ "^[#]*$"

which means if line contains only the # character, print that line and print the line required and the condition && NF to ensure the regex doesn't match blank lines for performing the new line insertion. The /Branch Owner/{flag=1; next} is to ensure no other similar tags are matched for appending below.

The part -v string="${pastestring}" imports the variable in bash context to the context of Awk since them both being different.

In-case, you want to over-write the file with the new contents, create a temporary file from the output of awk and re-direct it back to the original file ( equivalent of your sed in-place editing)

awk -v string="${pastestring}" '/Branch Owner/{print; flag=1; next}$0 ~ "^[#]*$" && flag && NF{print; print string; flag=0; next}1' "$file" > temp && mv temp "$file"

Upvotes: 1

Juan Diego Godoy Robles
Juan Diego Godoy Robles

Reputation: 14945

A Perl solution that performs an inplace replacement and checks Mail pattern:

perl -0777  -i -pne 's/(Mail:[^\n]*\n#+\n)/\1\n##### Branch FREEZE enable\/disable\nFreeze: enable\n/g' your_file

$ cat your_file
######## Branch Owner #########
Owner: Jones Jane
Mail: [email protected]
###############################

##### Branch FREEZE enable/disable
Freeze: enable

##### Branch RELEASE enable/disable
Release: disable

##### Branch configuration enable/disable
Release: enable

##### Branch output enable/disable
Release: enable

Upvotes: 0

Related Questions