1

This question is different from others I've seen in stackoverflow since it has to look for a string inside special characters like] or), and replace in different text strings urls associated with a markdown text. In the other solutions I have found there is only text substitution, I can not find and replace in a loop with different text.

  1. I have these images in a text of markdown: ... ![Image 1](https://i.imgur.com/BHoO2Wr.png "Alt Text 1") ... ![Image 2](https://i.imgur.com/qNxviLS.png "Alt Text 2") ... And new images from imgur from this variables: NEW_IMG1="https://i.imgur.com/xY0DgmM.png" NEW_IMG2="https://i.imgur.com/E98NLTT.png"

How do I change the old images for the new ones in bash?

Change this: BHoO2Wr for xY0DgmM

  1. Second question:

If my images are like this: ... ![any text](https://i.imgur.com/BHoO2Wr.png "other text") ... ![another text](https://i.imgur.com/qNxviLS.png "another thing") ...

How do I change BHoO2Wr for xY0DgmM and qNxviLS for E98NLTT in bash?

  • 1
    This question is different from others I've seen in stackoverflow since it has to look for a string inside special characters like] or), and replace in different text strings urls associated with a markdown text. – Luis Miguel Delgado Mar 04 '19 at 16:57

2 Answers2

1

Now this looks like a job for sed :)

# The file containing your markup
FILE="myMarkdown.txt"
# A list of new URLs, first = [Image 1], second = [Image 2]...
IMG=("https://i.imgur.com/xY0DgmM.png" "https://i.imgur.com/E98NLTT.png")
COUNT=1

for i in "${IMG[@]}"; do
        sed -i "s#\[Image $COUNT\](https://i.imgur.com/\(.*\) \(\"Alt Text.*\")\)#\[Image $COUNT\]($i \2#" "$FILE"
        COUNT=$((COUNT+1))
done

Just save this as script, change the two first variables, and run it in your favorite bash interpreter :)

Orsiris de Jong
  • 2,819
  • 1
  • 26
  • 48
  • And if each image has a different name. For example, instead of [Image 1], for [Image portfolio], how do I do it? – Luis Miguel Delgado Mar 01 '19 at 11:33
  • Sed without g does only one replace so if you remove the \[Image $COUNT\] blocks from the sed command, it will do one image, reload next URL and do next image with that. – Orsiris de Jong Mar 01 '19 at 15:00
  • If the images are: `![another text](https://i.imgur.com/qNxviLS.png "another thing") and ![any text](https://i.imgur.com/BHoO2Wr.png "other text")`, how can i solve it? – Luis Miguel Delgado Mar 01 '19 at 16:24
  • Well... Remove the part you don't need...Replace the sed line with ```sed -i "s#\](https://i.imgur.com/\(.*\) \(\"Alt Text.*\")\)#\]($i \2#" "$FILE"``` – Orsiris de Jong Mar 03 '19 at 15:05
1

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

$ NEW_IMG1="https://i.imgur.com/xY0DgmM.png"
$ NEW_IMG2="https://i.imgur.com/E98NLTT.png"

$ awk -v new="$NEW_IMG1 $NEW_IMG2" '
    BEGIN { split(new,images) }
    match($0,/^(!\[Image *([0-9]+)]\()[^ ]*(.*)/,a) {
        $0=a[1] images[a[2]] a[3]
    }
1' file
...
![Image 1](https://i.imgur.com/xY0DgmM.png "Alt Text 1")
...
![Image 2](https://i.imgur.com/E98NLTT.png "Alt Text 2")
...

if your images are actually just to be replaced in the order they appear rather than by the number in the input file ([Image 1], etc.) then it'd be:

match($0,/^(!\[Image[^]]+]\()[^ ]*(.*)/,a) {
    $0=a[1] images[++cnt] a[2]
}

and to match any text inside the square brackets:

match($0,/^(!\[[^]]+]\()[^ ]*(.*)/,a) {
    $0=a[1] images[++cnt] a[2]
}
Ed Morton
  • 188,023
  • 17
  • 78
  • 185