How to Modify a File Using SED

Close up motherboard shot

I started with a Microchip example and found out that one of the Makefiles generated by using the Makefile generator command, prjMakefilesGenerator has invalid paths. Therefore, I decided to use SED to modify the Makefile instead of open the file and change it every time. The following is the usage of the Makefile generator command.

prjMakefilesGenerator -v <PATH_TO_MICROCHIP_PROJECT>

# Example
PROJ_PATH="projects/microchip/same70_xult/mplab/aws_demos/firmware/aws_demos.X"
prjMakefilesGenerator -v ${PROJ_PATH

Once the Makefiles are generated, it is time to build the project.

pushd ${PROJ_PATH}
make clean
make all
popd

Unfortunately, it builds failed and throws this error.

--------------------------------------
User defined post-build step: [/opt/microchip/xc32/v2.41/bin\\xc32-objcopy -p -I ihex -O binary dist/same70_xult_nvm/production/aws_demos.X.production.hex dist/same70_xult_nvm/production/aws_demos.X.production.bin]
/bin/sh: 1: /opt/microchip/xc32/v2.41/binxc32-objcopy: not found
nbproject/Makefile-same70_xult_nvm.mk:108: recipe for target '.build-conf' failed
make[2]: *** [.build-conf] Error 127
make[2]: Leaving directory '/microchip-mqtt/projects/microchip/same70_xult/mplab/aws_demos/firmware/aws_demos.X'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed
make[1]: *** [.build-impl] Error 2
make[1]: Leaving directory '/microchip-mqtt/projects/microchip/same70_xult/mplab/aws_demos/firmware/aws_demos.X'
nbproject/Makefile-impl.mk:54: recipe for target '.all-impl' failed
make: *** [.all-impl] Error 2

From the first line of the log, we can see the path to xc32-objcopy is not correctly converted to forward slash. SED is the hero that saves the day. SED command is a stream editor that can perform insertion, deletion, and substitution of text. What we need from SED is basically search for the incorrect path and replace it with the valid path.

# sed command for substituing string
$sed "s/<SEARCHING_PATTERN>/<REPLACEMENT_STRING>/" <PATH_TO_THE_FILE>

# Example
$cat example.txt
This file has invalid paths

$sed "s/invalid/valid/" example.txt
This file has valid paths

The s character in the string specifies the substitution operation and the forward slashes / are delimiters. By running the command above, it only prints out the content with the substituted string. Therefore, we want to add the -i option for in-place substitution.

if [[ -e ${FILE_TO_BE_MODIFIED} ]]; then
    sed -i "s/<SEARCHING_PATTERN>/<REPLACEMENT_STRING>/g" ${FILE_TO_BE_MODIFIED}
fi

We first check if the file that is needed to be modified exists. If it does, then modify the file in-place. The g character at the end of the string means global replacement. In our case, we want to change the back-slashes in the Makefile to forward-slashes. By adding the if-statement above before calling make resolves the issue and the code builds successfully.

PROJ_PATH="projects/microchip/same70_xult/mplab/aws_demos/firmware/aws_demos.X"
PROJ_CONF="same70_xult_nvm"

pushd ${PROJ_PATH}
if [[ -e nbproject/Makefile-${PROJ_CONF}.mk ]]; then
    sed -i "s/\\\\\\/\\//g" nbproject/Makefile-${PROJ_CONF}.mk
fi
make clean
make all
popd

SED is a pretty sweet tool for modifying a file on the go. There are times when you want to find and replace the same line in many files or modify a config file such as a Doxyfile with output directory and project name, SED will come in handy.

And if you have questions about an embedded project you’re working on, Dojo Five can help you with all aspects of your devops for embedded journey! We are always happy to hear about cool projects or interesting problems to solve, so don’t hesitate to reach out and chat with us on LinkedIn or through email!

Leave a Reply

Your email address will not be published. Required fields are marked *