How to use sed within the same line behind match expression

Viewed 258

I got a text:

cat README.md | grep "####.*"                                    
#### Creating a helm chart with 2 child helm chart helm v3
#### Check you helmchart repositories
#### List content of your main-helmchart
#### Helm v3 dependency update
#### Check the content of charts/ folder in main-helmchart/
#### Check what is going to be installed

and I am trying to make it look like this:

  - [Creating a helm chart with 2 child helm chart helm v3](#creating-a-helm-chart-with-2-child-helm-chart-helm-v3)
  - [Check you helmchart repositories](#check-you-helmchart-repositories)
  - [List content of your main-helmchart](#list-content-of-your-main-helmchart)
  - [Helm v3 dependency update](#helm-v3-dependency-update)
  - [Check the content of charts/ folder in main-helmchart/](#check-the-content-of-charts/-folder-in-main-helmchart/)
  - [Check what is going to be installed](#check-what-is-going-to-be-installed)

is there any way to use sed for this ?

I am trying to match everything behind "#" sign and replace spaces for dash "-"

cat README.md | sed -E -n  's/^([#]{4}\s)(.*)$/- [\2](#\L\2)/p'  | sed -E  '/#.*/ s/ /-/g'  
--[Creating-a-helm-chart-with-2-child-helm-chart-helm-v3](#creating-a-helm-chart-with-2-child-helm-chart-helm-v3)
--[Check-you-helmchart-repositories](#check-you-helmchart-repositories)
--[List-content-of-your-main-helmchart](#list-content-of-your-main-helmchart)
--[Helm-v3-dependency-update](#helm-v3-dependency-update)
--[Check-the-content-of-charts/-folder-in-main-helmchart/](#check-the-content-of-charts/-folder-in-main-helmchart/)
--[Check-what-is-going-to-be-installed](#check-what-is-going-to-be-installed)

any advise ?

Thx

2 Answers

With GNU sed

$ sed -E 's/^#+ (.*)/- [\1](#\L\1)/; :a s/(\(#[^ ]+) /\1-/g; ta' ip.txt
- [Creating a helm chart with 2 child helm chart helm v3](#creating-a-helm-chart-with-2-child-helm-chart-helm-v3)
- [Check you helmchart repositories](#check-you-helmchart-repositories)
- [List content of your main-helmchart](#list-content-of-your-main-helmchart)
- [Helm v3 dependency update](#helm-v3-dependency-update)
- [Check the content of charts/ folder in main-helmchart/](#check-the-content-of-charts/-folder-in-main-helmchart/)
- [Check what is going to be installed](#check-what-is-going-to-be-installed)
  • s/^#+ (.*)/- [\1](#\L\1)/ this matches the #### Heading and converts to - [Heading](#heading) format
  • :a s/(\(#[^ ]+) /\1-/g; ta this is a loop to replace all spaces found after (#

Note that you can replace your cat+grep+sed+etc into single command with sed -nE '/^#### /{s/^#+ (.*)/- [\1](#\L\1)/; :a s/(\(#[^ ]+) /\1-/g; ta; p}' ip.txt


With perl

$ perl -pe 's/#+ (.+)/"- [$1](#" . lc($1) =~ tr| |-|r. ")"/e' ip.txt 
- [Creating a helm chart with 2 child helm chart helm v3](#creating-a-helm-chart-with-2-child-helm-chart-helm-v3)
- [Check you helmchart repositories](#check-you-helmchart-repositories)
- [List content of your main-helmchart](#list-content-of-your-main-helmchart)
- [Helm v3 dependency update](#helm-v3-dependency-update)
- [Check the content of charts/ folder in main-helmchart/](#check-the-content-of-charts/-folder-in-main-helmchart/)
- [Check what is going to be installed](#check-what-is-going-to-be-installed)

Perl allows perl code in replacement section with e flag. So you can do it all in single substitution. lc is for lowercase conversion, tr is for replacing space with - and so on.

For filter+substitution, use perl -ne 'print s/#+ (.+)/"- [$1](#" . lc($1) =~ tr| |-|r. ")"/re if /^#### /' ip.txt

This might work for you (GNU sed):

sed -E '/^#### /{s///;h;y/ /-/;H;g;s/(.*)\n(.*)/   - [\1](#\2)/}' file

For lines that begin ####, remove the hashes.

Copy the remainder to the hold space (HS).

Replace all spaces by -'s.

Append the amended line to the HS.

Replace current line by the HS.

Enclose the first line by sqare brackets and prepend three spaces a dash and a space, remove the newline, prepend the second line by a hash and enclose in parens.

Related