Featured image of post How to use SED in a Jenkins Pipeline

How to use SED in a Jenkins Pipeline

How to use sed command in a Jenkinsfile

Have you ever encountered the need to modify a single line in a file? While there are various utilities for this task, I consider sed to be superior to other 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:

1
2
3
4
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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
sh """#!/bin/bash
   # Print current version
   cat app.yml | grep version
   
   # Update version using sed
   sed -i 's|^version: .*|^version: "${VERSION}"|' app.yml
   
   # Print updated version
   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; meaning sed will update the file. You can provide a suffix after the parameter, and sed 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.

Feel free to integrate and adapt this approach to your projects. It’s a clean and efficient way to handle file updates within a Jenkins pipeline.