I have a file and I am trying to find and replace a string of text. The contents of the file are:
/**
* Version: 1.5.1
* Tested up to: 5.8
**/
I am trying to append the commit hash onto the version number inside of a file using a combination of awk and sed, but am having a difficult time. Previously, this was working just fine but is no longer working properly:
VERSION_LINE=$(awk '/\* Version:/' style.css)
COMMIT_HASH=$(git rev-parse --verify HEAD | head -c 7)
sed -i -e "${VERSION_LINE}s/$/-${COMMIT_HASH}/" style.css
I expect $VERSION_LINE
to return * Version: 1.5.1
but Checking contents it, it's actually returning a bunch of file names (which don't contain the string) AND that line at the end.
$ echo $VERSION_LINE;
404.php LICENSE archive.php comments.php dist footer.php functions.php header.php includes index.php page.php partials readme.txt screenshot.png search.php searchform.php single.php style.css woocommerce woocommerce.php Version: 1.5.1
But when I run awk '/\* Version:/' style.css
it does return the correct line, but storing it in a variable via VERSION_LINE=$(awk '/\* Version:/' style.css)
is returning a bunch of file names. Why the difference?
Trying the following is also returning the incorrect value:
$ $VERSION_LINE=$(cat style.css | grep '* Version:')
$ -bash: 404.php: command not found
Works Fine:
$ awk '/\* Version:/' style.css
$ * Version: 1.5.1
Does Not Work:
$ VERSION_LINE=$(awk '/Version:/' style.css)
$ echo $VERSION_LINE
404.php Gruntfile.js LICENSE README.md archive.php changelog.txt comments.php composer.json composer.lock cypress.json docs footer.php functions.php header.php includes index.php languages manifest.xml package.json page.php partials phpcs.xml phpunit.xml postcss.config.js readme.txt screenshot.png search.php searchform.php single.php style.css vendor woocommerce woocommerce.php yarn.lock Version: 1.5.1
Current Version of Bash:
$ bash --version
$ GNU bash, version 5.1.4(1)-release (x86_64-pc-linux-gnu)
CodePudding user response:
You can do this with awk
only:
awk -v hash="${COMMIT_HASH}" '/\* Version:/{$3=$3""hash}1' style.css > style.css.tmp \
&& mv style.css.tmp style.css
CodePudding user response:
The immediate problem is that you need to quote the assignment to prevent the shell from expanding the literal *
:
tripleee$ ls
foo bar baz
tripleee$ poo=$(echo '*')
tripleee$ echo "$poo"
foo bar baz
tripleee$ poo="$(echo '*')"
tripleee$ echo "$poo"
*
But the whole diversion to use Awk to find the line you want to replace is unnecessary (and basically a variation of Counting lines or enumerating line numbers so I can loop over them - why is this an anti-pattern?) -- you can easily use sed
itself to find the line.
commit_hash=$(git rev-parse --verify HEAD | head -c 7)
sed -i -e "/\* Version:/s/$/-${commit_hash}/" style.css
(Notice also the use of lower case for private variables.)