How to make a (sed) regex replacing all occurances of one character while deleting the last?
Clash Royale CLAN TAG#URR8PPP
up vote
2
down vote
favorite
I am struggling with the following.
I am using commands like this in my Mac terminal to test my regex:
echo 'inputstring' | sed (-E) '/s///g'
I am trying to create a regex that:
- if and only if a word ends in the letter 'o', then:
- deletes this word-final 'o'
- replaces all occurrences of the letter 'i' to 'a' in this word
In this case, the inputstring is filo fililo felo fale
and the expected output is fal falal fel fale
I can make a regex that does either the deletion or the replacement, but do not see how to combine them. If I put a semi column between them, I don't see how to put in the conditional part.
I am also having trouble defining 'the end of the word' position. I used b
but it doesn't seem to work (unlike $
for end of string).
sed regular-expression
add a comment |Â
up vote
2
down vote
favorite
I am struggling with the following.
I am using commands like this in my Mac terminal to test my regex:
echo 'inputstring' | sed (-E) '/s///g'
I am trying to create a regex that:
- if and only if a word ends in the letter 'o', then:
- deletes this word-final 'o'
- replaces all occurrences of the letter 'i' to 'a' in this word
In this case, the inputstring is filo fililo felo fale
and the expected output is fal falal fel fale
I can make a regex that does either the deletion or the replacement, but do not see how to combine them. If I put a semi column between them, I don't see how to put in the conditional part.
I am also having trouble defining 'the end of the word' position. I used b
but it doesn't seem to work (unlike $
for end of string).
sed regular-expression
post the actual, testable input string
â RomanPerekhrest
Nov 19 '17 at 20:28
Good point, I just added this to the description. As well as the expected outcome.
â Triplesmeg
Nov 19 '17 at 20:34
sed won't be good for such case. Useawk
instead
â RomanPerekhrest
Nov 19 '17 at 20:49
sed idea; replace words that end in 'o' with '#word#' with stripped 'o', replace all 'i' between two '#' with 'a', remove all '#' that appear immediately before/after a word (replace my example '#' with any suitable character).
â Hannu
Nov 19 '17 at 21:22
add a comment |Â
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I am struggling with the following.
I am using commands like this in my Mac terminal to test my regex:
echo 'inputstring' | sed (-E) '/s///g'
I am trying to create a regex that:
- if and only if a word ends in the letter 'o', then:
- deletes this word-final 'o'
- replaces all occurrences of the letter 'i' to 'a' in this word
In this case, the inputstring is filo fililo felo fale
and the expected output is fal falal fel fale
I can make a regex that does either the deletion or the replacement, but do not see how to combine them. If I put a semi column between them, I don't see how to put in the conditional part.
I am also having trouble defining 'the end of the word' position. I used b
but it doesn't seem to work (unlike $
for end of string).
sed regular-expression
I am struggling with the following.
I am using commands like this in my Mac terminal to test my regex:
echo 'inputstring' | sed (-E) '/s///g'
I am trying to create a regex that:
- if and only if a word ends in the letter 'o', then:
- deletes this word-final 'o'
- replaces all occurrences of the letter 'i' to 'a' in this word
In this case, the inputstring is filo fililo felo fale
and the expected output is fal falal fel fale
I can make a regex that does either the deletion or the replacement, but do not see how to combine them. If I put a semi column between them, I don't see how to put in the conditional part.
I am also having trouble defining 'the end of the word' position. I used b
but it doesn't seem to work (unlike $
for end of string).
sed regular-expression
edited Aug 20 at 22:12
Rui F Ribeiro
35.8k1271114
35.8k1271114
asked Nov 19 '17 at 20:25
Triplesmeg
113
113
post the actual, testable input string
â RomanPerekhrest
Nov 19 '17 at 20:28
Good point, I just added this to the description. As well as the expected outcome.
â Triplesmeg
Nov 19 '17 at 20:34
sed won't be good for such case. Useawk
instead
â RomanPerekhrest
Nov 19 '17 at 20:49
sed idea; replace words that end in 'o' with '#word#' with stripped 'o', replace all 'i' between two '#' with 'a', remove all '#' that appear immediately before/after a word (replace my example '#' with any suitable character).
â Hannu
Nov 19 '17 at 21:22
add a comment |Â
post the actual, testable input string
â RomanPerekhrest
Nov 19 '17 at 20:28
Good point, I just added this to the description. As well as the expected outcome.
â Triplesmeg
Nov 19 '17 at 20:34
sed won't be good for such case. Useawk
instead
â RomanPerekhrest
Nov 19 '17 at 20:49
sed idea; replace words that end in 'o' with '#word#' with stripped 'o', replace all 'i' between two '#' with 'a', remove all '#' that appear immediately before/after a word (replace my example '#' with any suitable character).
â Hannu
Nov 19 '17 at 21:22
post the actual, testable input string
â RomanPerekhrest
Nov 19 '17 at 20:28
post the actual, testable input string
â RomanPerekhrest
Nov 19 '17 at 20:28
Good point, I just added this to the description. As well as the expected outcome.
â Triplesmeg
Nov 19 '17 at 20:34
Good point, I just added this to the description. As well as the expected outcome.
â Triplesmeg
Nov 19 '17 at 20:34
sed won't be good for such case. Use
awk
insteadâ RomanPerekhrest
Nov 19 '17 at 20:49
sed won't be good for such case. Use
awk
insteadâ RomanPerekhrest
Nov 19 '17 at 20:49
sed idea; replace words that end in 'o' with '#word#' with stripped 'o', replace all 'i' between two '#' with 'a', remove all '#' that appear immediately before/after a word (replace my example '#' with any suitable character).
â Hannu
Nov 19 '17 at 21:22
sed idea; replace words that end in 'o' with '#word#' with stripped 'o', replace all 'i' between two '#' with 'a', remove all '#' that appear immediately before/after a word (replace my example '#' with any suitable character).
â Hannu
Nov 19 '17 at 21:22
add a comment |Â
3 Answers
3
active
oldest
votes
up vote
1
down vote
Awk would be more accurate and flexible for such case:
awk ' for(i=1;i<=NF;i++)
if ($i~/o$/) sub(/o$/,"",$i); gsub("i","a",$i) 1' <<<"filo fililo felo fale"
The output:
fal falal fel fale
Alternative Python command line approach:
python -c 'import sys,re; s = sys.stdin.read().strip();
print(re.sub(r"b(S+)ob", lambda m: m.group(1).replace("i","a"), s))' <<<"filo fililo felo fale"
fal falal fel fale
add a comment |Â
up vote
1
down vote
I would not use sed
for this, but if this is an exercise to learn sed
, do a loop like this:
sed -E 's/$/ /
:a
s/i([[:alnum:]]*o[^[:alnum:]])/a1/
ta
s/([[:alnum:]]*)o([^[:alnum:]])/12/
ta
s/ $//'
- In the first line I add a whitespace at the end, so we can treat the line end like any word end. The last line removes that whitespace later.
- The
s
command in line 3 searches for occurences ofi
in a word ending witho
and replaces it witha
. Thet
command loops back to mark:a
to repeat this for alli
in allo
-ending words. - Now the fifth line removes the ending
o
and another loop. Note that from a word ending withoo
, both of them will get removed; it's unclear whether this is desired.
For references only, I use an sed
version supporting the o
option to the s
command meaning only to preserve the matched part and throw away the rest. Also it knows the h
in the replacement to replace by the contents of the hold space. This makes the task a one-liner:
sed -E ':a;h;s/([[:alnum:]]*)o($|[^[:alnum:]])/12/o;T;y/i/a/;x;s//h/;ba'
add a comment |Â
up vote
0
down vote
I'm not sure if this is possible to do with sed
(I suspect that it probably isn't), but it's really easy to do with Python! Here's a script that does exactly what you want:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""modify_strings.py"""
import sys
import re
import fileinput
# Iterate over lines of input
# (either read from files or from stdin)
for line in fileinput.input():
# Split each line into tokens and preserve whitespace
tokens = re.split(r'(s+)', line)
# Iterate over tokens
for token in tokens:
# If a word ends in 'o' then
# perform the desired transformation
if token.endswith('o'):
token = token[:-1].replace('i', 'a')
# Print out each token
sys.stdout.write(token)
You can run it like so:
echo 'filo fililo felo fale' | python modify_strings.py
And it produces the following output (as desired):
fal falal fel fale
If you really want sed
to be involved, then you can probably get what you want by augmenting it with a little shell scripting. That might look something like the following bash
script:
#!/usr/bin/env bash
# modify-strings.bash
for word in "$@"; do
if grep -q 'o$' <<<"$word"; then
echo -n "$word " | sed -e 's/i/a/g' -e 's/o$//';
else
echo -n "$word ";
fi;
done
echo
You would call this script like so:
bash modify-strings.bash filo fililo felo fale
Everything is possible withsed
, the question is whether it makes sense. In this case, I don't think so, see my answer for a solution.
â Philippos
Nov 20 '17 at 8:59
add a comment |Â
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Awk would be more accurate and flexible for such case:
awk ' for(i=1;i<=NF;i++)
if ($i~/o$/) sub(/o$/,"",$i); gsub("i","a",$i) 1' <<<"filo fililo felo fale"
The output:
fal falal fel fale
Alternative Python command line approach:
python -c 'import sys,re; s = sys.stdin.read().strip();
print(re.sub(r"b(S+)ob", lambda m: m.group(1).replace("i","a"), s))' <<<"filo fililo felo fale"
fal falal fel fale
add a comment |Â
up vote
1
down vote
Awk would be more accurate and flexible for such case:
awk ' for(i=1;i<=NF;i++)
if ($i~/o$/) sub(/o$/,"",$i); gsub("i","a",$i) 1' <<<"filo fililo felo fale"
The output:
fal falal fel fale
Alternative Python command line approach:
python -c 'import sys,re; s = sys.stdin.read().strip();
print(re.sub(r"b(S+)ob", lambda m: m.group(1).replace("i","a"), s))' <<<"filo fililo felo fale"
fal falal fel fale
add a comment |Â
up vote
1
down vote
up vote
1
down vote
Awk would be more accurate and flexible for such case:
awk ' for(i=1;i<=NF;i++)
if ($i~/o$/) sub(/o$/,"",$i); gsub("i","a",$i) 1' <<<"filo fililo felo fale"
The output:
fal falal fel fale
Alternative Python command line approach:
python -c 'import sys,re; s = sys.stdin.read().strip();
print(re.sub(r"b(S+)ob", lambda m: m.group(1).replace("i","a"), s))' <<<"filo fililo felo fale"
fal falal fel fale
Awk would be more accurate and flexible for such case:
awk ' for(i=1;i<=NF;i++)
if ($i~/o$/) sub(/o$/,"",$i); gsub("i","a",$i) 1' <<<"filo fililo felo fale"
The output:
fal falal fel fale
Alternative Python command line approach:
python -c 'import sys,re; s = sys.stdin.read().strip();
print(re.sub(r"b(S+)ob", lambda m: m.group(1).replace("i","a"), s))' <<<"filo fililo felo fale"
fal falal fel fale
edited Nov 19 '17 at 21:10
answered Nov 19 '17 at 20:57
RomanPerekhrest
22.4k12145
22.4k12145
add a comment |Â
add a comment |Â
up vote
1
down vote
I would not use sed
for this, but if this is an exercise to learn sed
, do a loop like this:
sed -E 's/$/ /
:a
s/i([[:alnum:]]*o[^[:alnum:]])/a1/
ta
s/([[:alnum:]]*)o([^[:alnum:]])/12/
ta
s/ $//'
- In the first line I add a whitespace at the end, so we can treat the line end like any word end. The last line removes that whitespace later.
- The
s
command in line 3 searches for occurences ofi
in a word ending witho
and replaces it witha
. Thet
command loops back to mark:a
to repeat this for alli
in allo
-ending words. - Now the fifth line removes the ending
o
and another loop. Note that from a word ending withoo
, both of them will get removed; it's unclear whether this is desired.
For references only, I use an sed
version supporting the o
option to the s
command meaning only to preserve the matched part and throw away the rest. Also it knows the h
in the replacement to replace by the contents of the hold space. This makes the task a one-liner:
sed -E ':a;h;s/([[:alnum:]]*)o($|[^[:alnum:]])/12/o;T;y/i/a/;x;s//h/;ba'
add a comment |Â
up vote
1
down vote
I would not use sed
for this, but if this is an exercise to learn sed
, do a loop like this:
sed -E 's/$/ /
:a
s/i([[:alnum:]]*o[^[:alnum:]])/a1/
ta
s/([[:alnum:]]*)o([^[:alnum:]])/12/
ta
s/ $//'
- In the first line I add a whitespace at the end, so we can treat the line end like any word end. The last line removes that whitespace later.
- The
s
command in line 3 searches for occurences ofi
in a word ending witho
and replaces it witha
. Thet
command loops back to mark:a
to repeat this for alli
in allo
-ending words. - Now the fifth line removes the ending
o
and another loop. Note that from a word ending withoo
, both of them will get removed; it's unclear whether this is desired.
For references only, I use an sed
version supporting the o
option to the s
command meaning only to preserve the matched part and throw away the rest. Also it knows the h
in the replacement to replace by the contents of the hold space. This makes the task a one-liner:
sed -E ':a;h;s/([[:alnum:]]*)o($|[^[:alnum:]])/12/o;T;y/i/a/;x;s//h/;ba'
add a comment |Â
up vote
1
down vote
up vote
1
down vote
I would not use sed
for this, but if this is an exercise to learn sed
, do a loop like this:
sed -E 's/$/ /
:a
s/i([[:alnum:]]*o[^[:alnum:]])/a1/
ta
s/([[:alnum:]]*)o([^[:alnum:]])/12/
ta
s/ $//'
- In the first line I add a whitespace at the end, so we can treat the line end like any word end. The last line removes that whitespace later.
- The
s
command in line 3 searches for occurences ofi
in a word ending witho
and replaces it witha
. Thet
command loops back to mark:a
to repeat this for alli
in allo
-ending words. - Now the fifth line removes the ending
o
and another loop. Note that from a word ending withoo
, both of them will get removed; it's unclear whether this is desired.
For references only, I use an sed
version supporting the o
option to the s
command meaning only to preserve the matched part and throw away the rest. Also it knows the h
in the replacement to replace by the contents of the hold space. This makes the task a one-liner:
sed -E ':a;h;s/([[:alnum:]]*)o($|[^[:alnum:]])/12/o;T;y/i/a/;x;s//h/;ba'
I would not use sed
for this, but if this is an exercise to learn sed
, do a loop like this:
sed -E 's/$/ /
:a
s/i([[:alnum:]]*o[^[:alnum:]])/a1/
ta
s/([[:alnum:]]*)o([^[:alnum:]])/12/
ta
s/ $//'
- In the first line I add a whitespace at the end, so we can treat the line end like any word end. The last line removes that whitespace later.
- The
s
command in line 3 searches for occurences ofi
in a word ending witho
and replaces it witha
. Thet
command loops back to mark:a
to repeat this for alli
in allo
-ending words. - Now the fifth line removes the ending
o
and another loop. Note that from a word ending withoo
, both of them will get removed; it's unclear whether this is desired.
For references only, I use an sed
version supporting the o
option to the s
command meaning only to preserve the matched part and throw away the rest. Also it knows the h
in the replacement to replace by the contents of the hold space. This makes the task a one-liner:
sed -E ':a;h;s/([[:alnum:]]*)o($|[^[:alnum:]])/12/o;T;y/i/a/;x;s//h/;ba'
edited Nov 20 '17 at 9:01
answered Nov 20 '17 at 8:30
Philippos
5,92211546
5,92211546
add a comment |Â
add a comment |Â
up vote
0
down vote
I'm not sure if this is possible to do with sed
(I suspect that it probably isn't), but it's really easy to do with Python! Here's a script that does exactly what you want:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""modify_strings.py"""
import sys
import re
import fileinput
# Iterate over lines of input
# (either read from files or from stdin)
for line in fileinput.input():
# Split each line into tokens and preserve whitespace
tokens = re.split(r'(s+)', line)
# Iterate over tokens
for token in tokens:
# If a word ends in 'o' then
# perform the desired transformation
if token.endswith('o'):
token = token[:-1].replace('i', 'a')
# Print out each token
sys.stdout.write(token)
You can run it like so:
echo 'filo fililo felo fale' | python modify_strings.py
And it produces the following output (as desired):
fal falal fel fale
If you really want sed
to be involved, then you can probably get what you want by augmenting it with a little shell scripting. That might look something like the following bash
script:
#!/usr/bin/env bash
# modify-strings.bash
for word in "$@"; do
if grep -q 'o$' <<<"$word"; then
echo -n "$word " | sed -e 's/i/a/g' -e 's/o$//';
else
echo -n "$word ";
fi;
done
echo
You would call this script like so:
bash modify-strings.bash filo fililo felo fale
Everything is possible withsed
, the question is whether it makes sense. In this case, I don't think so, see my answer for a solution.
â Philippos
Nov 20 '17 at 8:59
add a comment |Â
up vote
0
down vote
I'm not sure if this is possible to do with sed
(I suspect that it probably isn't), but it's really easy to do with Python! Here's a script that does exactly what you want:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""modify_strings.py"""
import sys
import re
import fileinput
# Iterate over lines of input
# (either read from files or from stdin)
for line in fileinput.input():
# Split each line into tokens and preserve whitespace
tokens = re.split(r'(s+)', line)
# Iterate over tokens
for token in tokens:
# If a word ends in 'o' then
# perform the desired transformation
if token.endswith('o'):
token = token[:-1].replace('i', 'a')
# Print out each token
sys.stdout.write(token)
You can run it like so:
echo 'filo fililo felo fale' | python modify_strings.py
And it produces the following output (as desired):
fal falal fel fale
If you really want sed
to be involved, then you can probably get what you want by augmenting it with a little shell scripting. That might look something like the following bash
script:
#!/usr/bin/env bash
# modify-strings.bash
for word in "$@"; do
if grep -q 'o$' <<<"$word"; then
echo -n "$word " | sed -e 's/i/a/g' -e 's/o$//';
else
echo -n "$word ";
fi;
done
echo
You would call this script like so:
bash modify-strings.bash filo fililo felo fale
Everything is possible withsed
, the question is whether it makes sense. In this case, I don't think so, see my answer for a solution.
â Philippos
Nov 20 '17 at 8:59
add a comment |Â
up vote
0
down vote
up vote
0
down vote
I'm not sure if this is possible to do with sed
(I suspect that it probably isn't), but it's really easy to do with Python! Here's a script that does exactly what you want:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""modify_strings.py"""
import sys
import re
import fileinput
# Iterate over lines of input
# (either read from files or from stdin)
for line in fileinput.input():
# Split each line into tokens and preserve whitespace
tokens = re.split(r'(s+)', line)
# Iterate over tokens
for token in tokens:
# If a word ends in 'o' then
# perform the desired transformation
if token.endswith('o'):
token = token[:-1].replace('i', 'a')
# Print out each token
sys.stdout.write(token)
You can run it like so:
echo 'filo fililo felo fale' | python modify_strings.py
And it produces the following output (as desired):
fal falal fel fale
If you really want sed
to be involved, then you can probably get what you want by augmenting it with a little shell scripting. That might look something like the following bash
script:
#!/usr/bin/env bash
# modify-strings.bash
for word in "$@"; do
if grep -q 'o$' <<<"$word"; then
echo -n "$word " | sed -e 's/i/a/g' -e 's/o$//';
else
echo -n "$word ";
fi;
done
echo
You would call this script like so:
bash modify-strings.bash filo fililo felo fale
I'm not sure if this is possible to do with sed
(I suspect that it probably isn't), but it's really easy to do with Python! Here's a script that does exactly what you want:
#!/usr/bin/env python2
# -*- coding: ascii -*-
"""modify_strings.py"""
import sys
import re
import fileinput
# Iterate over lines of input
# (either read from files or from stdin)
for line in fileinput.input():
# Split each line into tokens and preserve whitespace
tokens = re.split(r'(s+)', line)
# Iterate over tokens
for token in tokens:
# If a word ends in 'o' then
# perform the desired transformation
if token.endswith('o'):
token = token[:-1].replace('i', 'a')
# Print out each token
sys.stdout.write(token)
You can run it like so:
echo 'filo fililo felo fale' | python modify_strings.py
And it produces the following output (as desired):
fal falal fel fale
If you really want sed
to be involved, then you can probably get what you want by augmenting it with a little shell scripting. That might look something like the following bash
script:
#!/usr/bin/env bash
# modify-strings.bash
for word in "$@"; do
if grep -q 'o$' <<<"$word"; then
echo -n "$word " | sed -e 's/i/a/g' -e 's/o$//';
else
echo -n "$word ";
fi;
done
echo
You would call this script like so:
bash modify-strings.bash filo fililo felo fale
edited Nov 19 '17 at 23:40
answered Nov 19 '17 at 20:51
igal
4,830930
4,830930
Everything is possible withsed
, the question is whether it makes sense. In this case, I don't think so, see my answer for a solution.
â Philippos
Nov 20 '17 at 8:59
add a comment |Â
Everything is possible withsed
, the question is whether it makes sense. In this case, I don't think so, see my answer for a solution.
â Philippos
Nov 20 '17 at 8:59
Everything is possible with
sed
, the question is whether it makes sense. In this case, I don't think so, see my answer for a solution.â Philippos
Nov 20 '17 at 8:59
Everything is possible with
sed
, the question is whether it makes sense. In this case, I don't think so, see my answer for a solution.â Philippos
Nov 20 '17 at 8:59
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f405651%2fhow-to-make-a-sed-regex-replacing-all-occurances-of-one-character-while-deleti%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
post the actual, testable input string
â RomanPerekhrest
Nov 19 '17 at 20:28
Good point, I just added this to the description. As well as the expected outcome.
â Triplesmeg
Nov 19 '17 at 20:34
sed won't be good for such case. Use
awk
insteadâ RomanPerekhrest
Nov 19 '17 at 20:49
sed idea; replace words that end in 'o' with '#word#' with stripped 'o', replace all 'i' between two '#' with 'a', remove all '#' that appear immediately before/after a word (replace my example '#' with any suitable character).
â Hannu
Nov 19 '17 at 21:22