Search code examples
groovysedjenkins-groovy

Problem with sed command in Jenkinsfile in Groovy


I'm trying to use sed in a Groovy file that is being executed by a Jenkinsfile.

My code is:

sh script: """
sed -i '' "s/search/substitute/g" "path/to/file"
"""

The intention is to change the search elements within a file path/to/file to substitute.

I can confirm the sed code, if executed manually in a terminal, works correctly.

But I'm getting the following error: sed: can't read s/search/substitute/g: No such file or directory

I've tried to invert the order of the search and path arguments without success.

When I get that error the quotes around s/search/substitute/g don't appear but

I've tried 's/search/substitute/g', "s/search/substitute/g", \"s/search/substitute/g\" and \'s/search/substitute/g\' getting the same error.

What am I doing wrong?


Solution

  • Apparently your sed version does not require an argument for the -i option. Thus '' is interpreted as your script, and s/search/substitute/g as the name of a file to process.

    Generally, BSD (and thus Mac) sed requires an argument to -i, whereas Linux doesn't.

    Assuming your Jenkins can reliably be expected to run Linux, the simplest solution is to just drop the ''.

    If you want to create a script which works regardless of platform, maybe pass a non-empty argument directly after -i, like -i~. (Probably take care to remove the file it creates afterwards. In case it's not obvious, this tells sed to save the original input file with a tilde after its name.)

    Another solution is to switch to Perl, which supports the same option and roughly similar syntax for substitutions; though note that Perl's regex dialect has many features which are absent from traditional sed (but basically backwards-compatible with the ERE dialect available in some sed implementations with -E or -r). Perhaps most notably if you are coming from sed, don't backslash grouping parentheses, the + and ? quantifers, etc.

    perl -pi -e "s/search/substitute/g" "path/to/file"
    

    Using double quotes around the sed or Perl script is pesky; probably prefer single quotes unless you specifically require the shell to perform variable expansion and command substitution when parsing the command line. (Even then, it's often convenient to use single quotes around the parts which don't require the shell to meddle.)

    sed -i 's/static text/'"$variable and $(command output)"'/g' path/to/file