I am trying to pipe output from git to sed, which will inturn replace a value in file.config that represents the last commit on a branch.
I am unsure how to do this using piping in bash. I thought maybe something like this? But it doesnt work (outputs nothing)
git rev-parse --short HEAD | sed -i 's/"commit".*:.*".*"/"commit": "${$_}"/g' file.config
Is this even possible, or is there a better approach I can take?
Contents of file.config
{
"commit" : "684e8ba31"
}
Contents of file.config (after running command)
{
"commit" : "${$_}"
}
Contents of file.config (expected output)
{
"commit" : "441d6fc22"
}
Ouput from git rev-parse --short HEAD
441d6fc22
CodePudding user response:
sed -i '/"commit" *:/s/: *"[^"]*"/: "'$(git rev-parse HEAD)'"/' file.config
will do it. You're confusing command-line arguments with stdin input. They're both good and widely-used ways of feeding the invoked program data but the differences in capacity and timing matter, so spend more time studying how they work.
CodePudding user response:
Simulating output from git
call:
$ cat git.out
441d6fc22
One idea where we capture the git
output to a variable and then feed the variable to sed
:
$ read -r sha < <(cat git.out)
$ sed -E "s/^(.*\"commit\"[^\"]*).*/\1\"${sha}\"/" file.config
{
"commit" : "441d6fc22"
}
Where:
-E
- enable extended regex support(.*\"commit\"[^\"]*)
- (1st capture group) everything from start of line up to and including"commit"
and then everything that follows up to the first occurrence of a literal"
.*
rest of line\1\"${sha}"\"
- replace with contents of 1st capture group followed by literal"
, contents ofsha
variable and another literal"
Once satisified with the result the -i
option can be added:
$ sed -Ei "s/^(.*\"commit\"[^\"]*).*/\1\"${sha}\"/" file.config
$ cat file.config
{
"commit" : "441d6fc22"
}
Pulling original git
call into the mix:
read -r sha < <(git rev-parse --short HEAD)
sed -Ei "s/^(.*\"commit\"[^\"]*).*/\1\"${sha}\"/" file.config