2

I did extensive searching and found many similar questions, but did not find one that actually did what I wanted, as far as I could tell.

Here is the closest question: Using sed in a makefile; how to escape variables?

A very simplified version of what I want to do inside the Makefile is

sed s~foo~${BAR}~

where $BAR is a variable in my makefile. Obviously, I want to replace foo with the value of $BAR not with the text ${BAR} as is currently happening.

Since it was requested, here is the full version:
Note, the goal is to have the Makefile be POSIX.

Makefile (relevant part only):

...
diff:
    scripts/build/diff-all.sh
...

scripts/build/diff-all.sh

#!/bin/bash -e

for DIFFBRANCH in $(cat diff-branches); do
    scripts/build/diff.sh $DIFFBRANCH
done

diff-branches

2016_reorg_diff
# more branches here

scripts/build/diff.sh

#/bin/bash -e

DIFFBRANCH=$1
BRANCH=$(git rev-parse --abbrev-ref HEAD)
CHAPTERDIR=src/chapters
SHORTCHAPTERDIR=${CHAPTERDIR##src/} # remove src/ from the start of CHAPTERDIR
CHAPTERS=$(ls $CHAPTERDIR | grep "^\\d\\d_.*\\.tex$")

LATEXARGS="-file-line-error -halt-on-error"

if [[ ! $DIFFBRANCH ]]; then
    echo "usage: $0 DIFFBRANCH"
    exit 1
fi

mkdir -p tmp
mkdir -p pdf

for CHAPTER in $CHAPTERS; do # make tex diff files for each chapter
    SLUG=$(echo $CHAPTER | cut -f 1 -d '.')
    latexdiff-vc --git --so --flatten  --force -r $DIFFBRANCH -r $BRANCH $CHAPTERDIR/$CHAPTER
    mkdir -p tmp/$CHAPTERDIR
    mv -v $CHAPTERDIR/$SLUG-diff$DIFFBRANCH-$BRANCH.tex tmp/src_diff_$DIFFBRANCH/$SHORTCHAPTERDIR/$SLUG-$BRANCH-diff-$DIFFBRANCH.tex
done

rsync -avz --exclude $SHORTCHAPTERDIR src/ tmp/src_diff_$DIFFBRANCH/ # copy all source files to tmp except chapters (because they're already there)

sed -i.bak -E 's~^([[:blank:]]*\subimport{chapters/}{[[:alnum:]_]+)}~\1-$BRANCH-diff-$DIFFBRANCH}~' tmp/src_diff_$DIFFBRANCH/iuf-rulebook.tex 
# this replaces \subimport{chapters/}{01_general} with \subimport{chapters/}{01_general-$BRANCH-diff-$DIFFBRANCH} with the variables expanded
# so that the iuf-rulebook.tex uses the diffed chapters
# the -i.bak is required so SED works on OSX and Linux
rm -f tmp/src_diff_$DIFFBRANCH/*.bak # because of this, we have to delete the .bak files after


mkdir -p tmp/out_diff_$DIFFBRANCH
TEXINPUTS=tmp/src_diff_$DIFFBRANCH: latexmk -pdf $LATEXARGS -quiet -output-directory=./tmp/out_diff_$DIFFBRANCH tmp/src_diff_$DIFFBRANCH/iuf-rulebook.tex
mv tmp/out_diff_$DIFFBRANCH/iuf-rulebook.pdf pdf/iuf-rulebook-$BRANCH-diff-$DIFFBRANCH.pdf
rm -rf tmp/*_$DIFFBRANCH
Scott Wilton
  • 253
  • 4
  • 11
  • 2
    It's unclear what you mean "not with the text ${BAR}". The question you linked shows pretty much what I think you're asking about. `sed 's~foo~'${BAR}'~g'` should work... – l'L'l Jan 22 '17 at 06:59
  • @l'L'l No it shouldn't, ${BAR} may contain tildes, or spaces, or tabs, all of which will make your substitution fail. – Jens Jan 22 '17 at 13:45
  • Show us your Makefile, especially the assignment to BAR and the target/rule where you use sed. Describe the resulting text you expect, and the actual result. – Jens Jan 22 '17 at 13:47
  • I've added the script. Note that ${BAR} will never contain spaces or tabs, and foreseeably will not contain tildes either. – Scott Wilton Jan 22 '17 at 16:59
  • The regex in `sed` came from another stackexchange question: https://stackoverflow.com/questions/41787537/using-sed-with-regex-to-replace-text-on-osx-and-linux – Scott Wilton Jan 22 '17 at 17:04
  • It looks to me like you need `sed -E "..."` rather than `sed -E '...'` -- the $BRANCH and $DIFFBRANCH strings won't be expanded within single quotes in your bash script. If you add `set -x` to the bash script, you should see that string expansion change. – stevesliva Jan 23 '17 at 16:24
  • @stevesliva thanks, after a lot of googling I've come to guess the same suggestion. However, when I change to double quotes, `sed` fails with `sed: 1: "s~^([[:blank:]]*\subimp ...": unterminated substitute in regular expression`. I'm guessing that means I need to escape something extra inside the quotes because of the switch to `"`. – Scott Wilton Jan 23 '17 at 17:37
  • It looks like it may be coming from the `\subimport` inside the double quote, namely the `\s` which may be expanded to space. If I am correct, what is the proper way to escape this? Or is it the `\1`? – Scott Wilton Jan 23 '17 at 17:54
  • Or the square brackets? I don't know... you might try single quotes nested in doubles, but I'm not a shell-expansion guru. – stevesliva Jan 23 '17 at 18:06
  • @stevesliva is your suggestion `sed -E "'...'"` or `sed -E '"..."'`? Plus wouldn't that negate the expansion of variables, like I want? I'm not sure. – Scott Wilton Jan 23 '17 at 18:14
  • The first. Single quotes have not special meaning within double, so they won't prevent variable expansion. But I'm beyond my predictive abilities and into throw-it-all-against-the-wall-and see what sticks... mostly because even with that suggestion I would have no good explanation for why it's necessary. – stevesliva Jan 23 '17 at 18:22
  • @stevesliva that returned a `invalid command code '` error. So I guess it didn't stick. Thanks for the suggestion though. – Scott Wilton Jan 23 '17 at 18:25
  • Makes me think sed is getting the expanded string as a single token... so perhaps you want to try `'s//...'"$VAR"'.../'`. Again complaining that I'm outside my scope of expertise, I can't say how that would work if $VAR contained whitespace. – stevesliva Jan 23 '17 at 18:41
  • @stevesliva that worked! My `$VAR` will never have whitespace in it. You can submit that as an answer and I'll accept it. – Scott Wilton Jan 24 '17 at 01:15

1 Answers1

0

Command:

sed -e s/number/$(BAR)/g 

To verify:

VAR = random number
VAR1 = file
FOO = $(VAR)
$(info before substitution: $(FOO))
FOO = $(shell echo $(VAR) | sed -e s/number/$(VAR1)/g )
$(info after substitution: $(FOO))