How to use SED in a Jenkins Pipeline

Have you ever had a task to update a single line in a file? There few utilities to help with that task,
and I find sed
superior on the alternatives.
sed
is a stream editor, with which you can modify files. It’s a great utility in your toolbox.
If you’re unfamiliar with it, here’s a [link
for a quick intro.
I had to use it in one of my Jenkins Pipelines. Since escaping commands in a pipeline is a nightmare , I had to debug it for a while until I got it working. If you have a similar task, this might save you some precious time.
The requirement was to update a line in a large file (couple hundreds of lines), with an arbitrary string provided as an input.
An elegant way of doing it with sed
is to capture the known prefix, up to a delimiter and then replace the whole thing comes next (until the end of line).
For example, we have the following file:
app: myapp
env: dev
version: 1.0
..
Now we want to update the version
part from Jenkins. How can we do it? When working with Jenkins, I recommend do it verbosly. Print the stuff before and after you change,
it would be much easier to debug later on. This is how I decided implementing it:
sh """#!/bin/bash
cat app.yml | grep version
sed -i 's|version: .*|version: "${VERSION}"|' app.yml
cat app.yml | grep version
"""
Using sh
module, with """ ... """
I can escape the escaping nightmare of groovy. Otherwise I would have to put multiple \\\\
in the command, up to the point it’s barely readable.
I also include #!/bin/bash
, to make sure I’m using bash shell.
Let’s break down the sed
command.
-i
means do the replacement in-place; meaningsed
will update the file. You can provide a suffix after the parameter, andsed
will create a backup version of the file before doing the update.'s|..#1..|..#2..|'
-s
is for substitute, #1 is the string, or pattern to look for and #2 is the replacement. The${VERSION}
variable is defined by Jenkins.- for #1, I’m looking for the prefix “version:” and then using regex to capture whatever comes next.
- for #2, I’m putting the full string I expect to be included in the final file.
There are other ways to achieve the same goal, but I find it a good practice to print stuff before and after an automatic job changes something in a file.