It turned out that I was not having an infinite loop, but I was experiencing this bug.
The service that modifies the file that I am monitoring, does not just modify the file, but deletes and recreates it. Through the deletion, incrond stops watching it, which can be determined when event IN_IGNORED is logged. That's why it always worked only once after a restart of incrond.
To not lose the watch on my file, I used the workaround also mentioned in the linked GitHub issue. Instead of monitoring the file directly, I monitor its parent directory. To not react to all other events in this directory I had to put my sed command into a script file and add a filter for the filename of my interest:
/etc IN_CLOSE_WRITE /home/user/myscript.sh $@ $#
With /home/user/myscript.sh:
#!/bin/bash
if [ "$2" == "file.md" ]; then
sed -i 's/Hello/Hi/g' "$1/$2"
fi
I also changed IN_MODIFY to IN_CLOSE_WRITE, because IN_MODIFY seemed to trigger some ms too early for my needs.
Fortunately, the above table won't create a loop, because sed -i won't modify or write to the file, but replacing it (IN_MOVE_TO), so no IN_MODIFY or IN_CLOSE_WRITE.