$ awk '{ gsub("-", "_", $1) } 1' FS=':' OFS=':' config.yml
scratch_org_def: config/project-scratch-def.json
assign_permset: false
permset_name:
run_apex_tests: true
apex_test_format: tap
delete_scratch_org: false
show_scratch_org_url: true
This awk script reads the file as a :-delimited set of fields. It applies gsub() to the first field on each line, changing every dash to an underscore. The lone 1 is short for { print } which will print each (now modified) input line.
FS=':' OFS=':' sets the input and output field separators to :.
It may be possible to do this with sed as well, either through some very complicated regular expression or by utilizing its hold-space (or both), but that's not a solution that "rolls off the tongue".
(after some thinking) Using sed:
$ sed 'h;s/^[^:]*//;x;s/:.*$//;y/-/_/;G;s/\n//' config.yml
scratch_org_def: config/project-scratch-def.json
assign_permset: false
permset_name:
run_apex_tests: true
apex_test_format: tap
delete_scratch_org: false
show_scratch_org_url: true
Explanation of each step:
h: Copy the pattern-space (the current input line) to the hold-space (a "general purpose" buffer).
s/^[^:]*//: Remove everything before the first : in the pattern-space.
x: Swap the hold-space and the pattern-space.
s/:.*$//: Remove the : and everything after it in the pattern-space.
The pattern-space now contains the unmodified left-hand side of the :, while the hold-space contains the unmodified right-hand side, including the :.
y/-/_/: Change all dashes to underscores in the pattern-space.
G: Append the hold-space to the end of the pattern-space with a newline between the two.
s/\n//: Remove that newline character from the previous step.
- (Implicit
p): Print the pattern-space to standard output.
Steps 4 and 5 may be interchanged without any change in result.
In short: sed is not (may not be) the right tool for the job.