Sungam
Sungam

Reputation: 1734

Replace a character in a section of a string in Bash

I'm trying to replace - and : with ? only in the middle(second) section delimited by ___ (3 underscore)

input:

aaa___bb-bb:bbb___cc-cc:ccc
d-d___d-ddd:d-d___e-e:e

output:

aaa___bb?bb?bbb___cc-cc:ccc
d-d___d?ddd?d?d___e-e:e

I tried below sed command but it only replaces the last occurrence of the -: in the middle section

echo "aaa___bb-bb:bbb___cc-cc:ccc
d-d___d-ddd:d-d___e-e:e" | sed "s|\(___[^_]*\)[-:]\([^_]*___\)|\1?\2|g"

Output:

aaa___bb-bb?bbb___cc-cc:ccc
d-d___d-ddd:d?d___e-e:e

I'm not restricted to only use sed. awk, tr, etc are fine too.

Upvotes: 1

Views: 100

Answers (3)

josifoski
josifoski

Reputation: 1726

You were close with sed solution

sed -r ':a; s/(___.*)[-:](.*___)/\1?\2/; ta' file

conditional branching is what you needed only

Upvotes: 1

Ell
Ell

Reputation: 947

Try:

awk -F"___" '{gsub(/[-:]/,"?",$2)}1' OFS="___"

Upvotes: 5

Charles Duffy
Charles Duffy

Reputation: 295815

In pure native bash, with no external utilities:

in='aaa___bb-bb:bbb___cc-cc:ccc
d-d___d-ddd:d-d___e-e:e'

while IFS= read -r line; do
   first=${line%%___*}
   last=${line##*___}
   middle=${line#*___}; middle=${middle%___*}
   printf '%s\n' "${first}___${middle//[-:]/?}___${last}"
done <<<"$in"

Upvotes: 3

Related Questions