Reputation: 11
I have a file that looks like this:
some text some text some text.
some other text. and others.
text text text ![Screenshot 2020-05-29 at 4.14.08 pm](./images/Screenshot 2020-05-29 at 4.14.08 pm.png)
![Screenshot 2020-05-29 at 4.04.08 pm](./images/Screenshot 2020-05-29 at 4.04.08 pm.png)
Some other text.
![Screenshot 2020-05-29 at 4.04.09 pm](./images/Screenshot 2020-05-29 at 4.04.09 pm.png) text text text
text text text ![Screenshot 2020-06-29 at 4.04.09 pm](./images/Screenshot 2020-06-29 at 4.04.09 pm.png) text text text
I want to replace the space with underscore in Screenshot names so that it becomes:
some text some text some text.
some other text. and others.
text text text ![Screenshot_2020-05-29_at_4.14.08_pm](./images/Screenshot_2020-05-29_at_4.14.08_pm.png)
![Screenshot_2020-05-29_at_4.04.08_pm](./images/Screenshot_2020-05-29_at_4.04.08_pm.png)
some other text.
![Screenshot_2020-05-29_at_4.04.09_pm](./images/Screenshot_2020-05-29_at_4.04.09_pm.png) text text text
text text text ![Screenshot_2020-06-29_at_4.04.09_pm](./images/Screenshot_2020-06-29_at_4.04.09_pm.png) text text text
Can sed do this?
If I use sed -e "s/ /_/g"
, then all spaces, not just those in Screenshot file names, would be changed. I don't want to replace spaces in other text.
Thanks to anyone that could help out!
Upvotes: 0
Views: 334
Reputation: 20002
When the screenshot string continues until the first )
or ]
, first put each screenshot string on a seperate line:
tr "\n" "\r" < "${file}" | sed -r 's/Screenshot|\]|\)/\n&/g' |
sed -r '/Screenshot/ s/ /_/g' | tr -d '\n' | tr '\r' '\n'
Upvotes: 0
Reputation: 785126
Looking at your sample data and your comment you may use this perl
:
perl -pe 's/(?:\[Screenshot|(?!^)\G[^] ]+)\K (?=[^]]*])|(?:\([^) ]*Screenshot|(?!^)\G[^) ]+)\K (?=[^)]*\))/_/g' file
some text some text some text.
some other text. and others.
text text text ![Screenshot_2020-05-29_at_4.14.08_pm](./images/Screenshot_2020-05-29_at_4.14.08_pm.png)
![Screenshot_2020-05-29_at_4.04.08_pm](./images/Screenshot_2020-05-29_at_4.04.08_pm.png)
Some other text.
![Screenshot_2020-05-29_at_4.04.09_pm](./images/Screenshot_2020-05-29_at_4.04.09_pm.png) text text text
text text text ![Screenshot_2020-06-29_at_4.04.09_pm](./images/Screenshot_2020-06-29_at_4.04.09_pm.png) text text text
RegEx Details:
(?:
: Start non-capture group
!\[Screenshot
: Match text ![ScreenShot
|
: OR(?!^)\G
: \G
asserts position at the end of the previous match or line start. (?!^)
ensures \G
doesn't match at line start.[^] ]+
: Match 1 or more of any character that is not space or ]
)
: End non-capture group
\K
: Reset Match Info
(?=[^]]*])
: Lookahead to ensure we have a ]
ahead of us
|(?:\([^) ]*Screenshot|(?!^)\G[^) ]+)\K (?=[^)]*\))
: Do same for (.*Screenshot.*.)
string
Upvotes: 1
Reputation: 58400
This might work for you (GNU sed):
sed '/^!\[Screenshot /y/ /_/' file
The y
command is seds translate command similiar to the tr
command line command.
If there is text before the text you want spaces underlined to remain with spaces in it, use this:
sed '/^!\[Screenshot /{s//\n&;h;y/_/ /;H;g;s/\n.*\n//}' file
This cuts the line in two, copies, amends and joins back the two parts, with the back half amended.
Upvotes: 0