Change special inline code styling to block code styling in Markdown

Viewed 183

I am using a unique style for demonstrating code in a tutorial written in Markdown.

With GitHub's new "Copy" button in code blocks (as of May '21), I want to change all my inline commands to block console code, thereby making my tutorials easier for students.

(You are welcome to see the actual tutorials if you want: VIP Linux)

My problem

Where 34 could be any numbers, letters, or Hyphen

And the comment may or may not exist

And all files end with .md

I want to change this:

| **34** :$ `one cli command here` Optional `code` comment, *maybe* with <kbd>Ctrl</kbd> + <kbd>Z</kbd>

...to this:

| **34** :$ Optional `code` comment, *maybe* with <kbd>Ctrl</kbd> + <kbd>Z</kbd>

```console
one cli command here
```

My research

I can use sed easily for part of this operation

sed 's/** :$ `/** :$\n```console\n/' *.md | sed 's:` :\n```\n\n:'

Changing:

| **10** :$ `some command` Some `code` *comment*

...to:

| **10** :$    
```console
some command
```

Some `code` *comment*

But, I need Some code *comment* to remain on the same line as | **10** :$


Why I'm asking

This may be a job for awk. Even if I understood awk, the necessary regex eludes me.

I may use text place holders in the final sed statement, then grep to change Optional code *comments* manually. But, I'd rather contribute to the community with a question, which could also save me time.

2 Answers

Use capture groups and backreferences:

$ cat ip.txt
| **10** :$ `some command` Some `code` *comment*

$ sed -E 's/(\*\* :\$) `([^`]+)`(.*)/\1\3\n\n```console\n\2\n```/' ip.txt
| **10** :$ Some `code` *comment*

```console
some command
```

(regexp) will capture the portion matched which you can recall later by using \1, \2, etc. The leftmost ( gets group number 1, next leftmost ( gets number 2 and so on.

With GNU awk for gensub():

$ awk '{$0=gensub(/([^`]*)`([^`]*)` (.*)/,"\\1\\3\n\n```console\n\\2\n```",1)} 1' file
| **34** :$ Optional `code` comment, *maybe* with <kbd>Ctrl</kbd> + <kbd>Z</kbd>

```console
one cli command here
```

or with GNU awk for the 3rd arg to match():

$ awk 'match($0,/([^`]*)`([^`]*)` (.*)/,a){$0=a[1] a[3] "\n\n```console\n" a[2] "\n```"} 1' file
| **34** :$ Optional `code` comment, *maybe* with <kbd>Ctrl</kbd> + <kbd>Z</kbd>

```console
one cli command here
```

or with any awk:

$ awk 'match($0,/`[^`]*`/){$0=substr($0,1,RSTART-1) substr($0,RSTART+RLENGTH+1) "\n\n```console\n" substr($0,RSTART+1,RLENGTH-2) "\n```"} 1' file
| **34** :$ Optional `code` comment, *maybe* with <kbd>Ctrl</kbd> + <kbd>Z</kbd>

```console
one cli command here
```
Related