2

I have a text file called branch.txt:

$ cat branch.txt
DEMAND_NAME-CR-1234
DEMAND_NAME-CR-8970

Using the above branch name, I have to find and replace some values using a sed command:

branch_name=`(cat /tmp/branch.txt)`
sed -i "s/deploy_branch/$branch_name/g" /tmp/input.file

When I run the sed command, I get an error like the one below:

sed: -e expression #1, char 35: unterminated `s' command

Expected output:

<Project description="first-deployment" name="DEMAND_NAME-CR-1234 DEMAND_NAME-CR-8970 " overwrite="true" type="Repository">
      </Project>

Input file:

<Project description="first-deployment" name="deploy_branch" overwrite="true" type="Repository">
      </Project>
Kusalananda
  • 320,670
  • 36
  • 633
  • 936
viswa
  • 23
  • 4
  • Please [edit] your question and show us your input file and the expected output. You have two lines in `branch.txt`, which one do you want to use? – terdon Oct 07 '22 at 12:50
  • Hi @ terdon, sorry for the trouble, i have updated the input file – viswa Oct 07 '22 at 12:58
  • branch name contain a new line character. sed is a line editor, so at every line you have a new command – Giacomo Catenazzi Oct 07 '22 at 13:10
  • Which of the lines in the `branch.txt` file do you want to use, or to put the question differently, what do you want your result to look like? – Kusalananda Oct 07 '22 at 13:12
  • Hi @ Kusalanda, i have added my expected output, actually the branch name content should be replaced with where the text contains (deploy_branch) – viswa Oct 07 '22 at 13:17
  • See [What characters do I need to escape when using sed in a sh script?](https://unix.stackexchange.com/a/33005) and [How to ensure that string interpolated into \`sed\` substitution escapes all metachars](https://unix.stackexchange.com/q/129059) – Stéphane Chazelas Oct 07 '22 at 13:37

1 Answers1

2

The issue with your sed command is that $branch_name contains an embedded newline character. This breaks the syntax of the substitution command in sed when you inject it into the sed editing expression.


Using xmlstarlet to update the name attribute of the document's Project root node to be the contents of the branch.txt file with each newline replaced by a space:

xmlstarlet edit \
    --update '/Project/@name' \
    --value "$(paste -s -d ' ' branch.txt)" input.file

or, shorter,

xmlstarlet ed \
    -u '/Project/@name' \
    -v "$(paste -s -d ' ' branch.txt)" input.file

The paste command in the command substitution reads the branch.txt file and replaces each newline, apart from the last, with a space character. This results in a string used as the new value for the name attribute. If you want to retain the final newline character and convert it into a trailing space (as in your expected output), then use tr '\n' ' ' <branch.txt in place of the paste command.

The xmlstarlet utility is invoked with its ed sub-command. This command edits an XML file, and we specify that we'd like to update a particular element via an XPath query matching the attribute.

Would you need to make the change only when the name attribute's value is deploy_branch, then use the XPath query /Project/@name[. = "deploy_branch"] or /Project[@name = "deploy_branch"]/@name instead.

The output of the above commands would be

<?xml version="1.0"?>
<Project description="first-deployment" name="DEMAND_NAME-CR-1234 DEMAND_NAME-CR-8970" overwrite="true" type="Repository">
      </Project>

The xmlstarlet tool can be made to make an in-place edit if you give it the --inplace (-L) option after ed or edit. You may avoid having the <?xml ...> declaration added by using --omit-decl (-O).

Kusalananda
  • 320,670
  • 36
  • 633
  • 936
  • Thanks for the update, i will try install xmlstarlet in my linux box then i will add above content in my azure pipeline – viswa Oct 07 '22 at 14:15
  • Hi @Kusalananda, above xmlstarlet command can able edit the file but not able save the content which is exist in branch.txt – viswa Oct 07 '22 at 17:11
  • can you please help me – viswa Oct 07 '22 at 17:11
  • @viswa Sorry, I don't understand. If you want to save the modified data back to the same filename, use `xmlstarlet ed --inline` followed by the rest of the command (I mentioned this in the last paragraph of my answer). – Kusalananda Oct 07 '22 at 17:15