1

I have been trying to add a string in the same line in a text file. I have used following method.

sed -i "s/\bmembers\b/& \t$host,/" printer.cfg

It will add a string after members string and also it will add tab in order to make it proper.

I will get result like this,

define hostgroup{
hostgroup_name  HOSTGROUP ONE   
alias       Host Group 1 Printers
members     foo0, foo1, bar2, foo2, bar3
}

Where foo0 is my added string using above sed.

But the problem is there is one text file, that contains many "members" string.

e.g.

define hostgroup{
hostgroup_name  HOSTGROUP ONE   
alias       Host Group 1 Printers
members     foo1, bar2, foo2, bar3
}

define hostgroup{
hostgroup_name  HOSTGROUP TWO
alias       2nd Host Group
members     example1, example3, example2
}

In this above example, I want to add string ONLY in first para (hostgroup_name HOSTGROUP ONE). In this case, How can I refer hostgroup_name and add text after "members" string with one tab?

1

Two approaches:

sed approach:

sed "0,/members/{s/\bmembers */&$host, /}" printer.cfg
  • 0,/members/ - address range occupying a range of lines starting from the 1st line till the first occurrence of members pattern

awk approach:

awk -v h=$host '!f && /members /{ $2=sprintf("%8s, %s",h,$2); f=1 }1' printer.cfg

The output (for both approaches):

define hostgroup{
hostgroup_name  HOSTGROUP ONE   
alias       Host Group 1 Printers
members     foo0, foo1, bar2, foo2, bar3
}

define hostgroup{
hostgroup_name  HOSTGROUP TWO
alias       2nd Host Group
members     example1, example3, example2
}
  • @BuvaneshKumar, you're welcome – RomanPerekhrest Jun 8 '17 at 5:51
  • Hi @RomanPerekhrest, Is there any way to add the string without referring number? Because the text file content will be larger day by day. Is it possible to refer "hostgroup_name" and add string in members line? – Buvanesh Kumar Jun 8 '17 at 6:29
  • @BuvaneshKumar, /hostgroup_name/,/members/ - this will capture all ranges within a file and cause to multiple replacements. So this 0,/members/ is suitable to replace only once. Also, consider my awk approach – RomanPerekhrest Jun 8 '17 at 6:47
  • I mean the variable (HOSTGROUP ONE) I allocated for hostgroup_name is constant. It will not change. So is there any way we can refer both that variable and members? – Buvanesh Kumar Jun 8 '17 at 6:56
  • @BuvaneshKumar, yes, in that case you can apply /hostgroup_name *HOSTGROUP ONE/,/members/ – RomanPerekhrest Jun 8 '17 at 7:31
0

Follow the 3-step process of selecting, storing, and shaping the range of interest data. The final task of printing to stdout is an autotask of sed.

host='Foo_0';
sed -Ee '

   # Step-1: SELECT RANGE
   /^define hostgroup[{]/,/^[}]/!b

   # Step-2: SAVE RANGE DATA
   H; /^define hostgroup[{]/h; /^[}]/!d

   # Step-3: SHAPE RANGE DATA
   g;/\nhostgroup_name\s+HOSTGROUP ONE/s/\nmembers\s+/&'"${host}"', /

' printer.cfg

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.