2

In my current directory (projDir), I have about 41 folders as follows:

  • ProgOneDir
  • ProgTwoDir
  • ProgThreeDir
  • ...
  • ProgFortyOneDir

...etc (I did not come up with the naming scheme and I am not a systems admin so please don't yell at me for them).

Inside each of the subfolders, there are README.md files I need to edit. Instead of going into each subfolder and editing the files there, I would like to use a sed command to do so. The files are consistently named README.md

I am running CentOS7

My current command is:

find . -name 'README.md' -exec sed -i -e 's/./makeprog $MAKE_FLAGS CFLAGS="-I/usr/local/include/libtool" OFLAGS="-L/usr/local/lib"/./makeprog/g' {} \;

Essentially, I need to switch:

./makeprog $MAKE_FLAGS CFLAGS="-I/usr/local/include/libtool" OFLAGS="-L/usr/local/lib

to

./makeprog

Would somebody be able to assist? The error I get is:

sed: -e expression #1, char 43: unknown option to `s'

I have already looked at:

I believe my error is arising with the ./command. I have followed advice of switching all / to +, but that still didn't work, as I got the following error:

sed: -e expression #1, char 110: unterminated `s' command

Thank you.

artemis
  • 6,857
  • 11
  • 46
  • 99
  • Hi @kvantour, I don't think it is. I saw that, but it isn't explicitly paths I'm concerned with, it is switching a command that contains ./ I found that article and tried following the advice of switching / to + and it still didn't work. – artemis Oct 17 '18 at 13:12
  • Basically you alreay have the correct command. Only failure: The slash character is part of your "pattern", that's why you either must escape it or use another "separator" for sed, for example the # char: `sed 's#./makeprog $MAKE_FLAGS CFLAGS="-I/usr/local/include/libtool" OFLAGS="-L/usr/local/lib"#./makeprog#g'` – rudi Oct 17 '18 at 13:13
  • The slashes give you the error 'unknown option to s`. The other problem is your dollar sign. You have to escape them. – kvantour Oct 17 '18 at 13:14
  • @kvantour $ signs don't matter as long as using single quotes. – rudi Oct 17 '18 at 13:14
  • @rudi, I was confused. I thought `$` had to be escaped due to the anchoring (http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03_08) – kvantour Oct 17 '18 at 13:20
  • 1
    @kvantour: that's true if `$` is at the end of the regexp. otherwise it's considered as a normal character. – rudi Oct 19 '18 at 14:34

1 Answers1

6

Your problem is that you are using slash as the delimiter to the s/// command, but you are putting slashes into the pattern. You can pick a different delimiter that does not appear in the pattern.

Assuming your current directory is projDir, and there is only one call to makeprog:

sed -i -E 's#(./makeprog) .*#\1#' */README.md

or

perl -i -e 's{./makeprog\K.*}{}' */README.md

If you want to specifically match that exact line, then:

# are you missing a trailing double quote?
line='./makeprog $MAKE_FLAGS CFLAGS="-I/usr/local/include/libtool" OFLAGS="-L/usr/local/lib'
sed -i -E "s#$line#./makeprog#" */README.md
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
  • Hi @glenn jackman, thank you for your answer. This worked perfectly. Might you be able to explain what the .*#\1# is doing, so that I may learn? – artemis Oct 17 '18 at 13:16
  • On the left hand side, the regex pattern, I put parentheses around `(./makeprog)`. In the right hand side, the replacement string, you can use `\n` to use the text matched in the `n`th parenthesised group. For documentation see [3.3 The `s` Command](https://www.gnu.org/software/sed/manual/html_node/The-_0022s_0022-Command.html#The-_0022s_0022-Command) – glenn jackman Oct 17 '18 at 13:21