catchkarthik
catchkarthik

Reputation: 129

replacing specific characters in a line shell script

I have the following contents in a file

{"Hi","Hello","unix":["five","six"]}

I would like to replace comma within the square brackets only to semi colon. Rest of the comma's in the line should not be changed.

Output should be

{"Hi","Hello","unix":["five";"six"]}

I have tried using sed but it is not working. Below is the command I tried. Kindly help.

sed 's/:\[*\,*\]/;/'

Thanks

Upvotes: 1

Views: 476

Answers (3)

etopylight
etopylight

Reputation: 1319

Awk would also be useful here

awk -F'[][]' '{gsub(/,/,";",$2); print $1"["$2"]"$3}' file

by using gsub, you can replace all occurrences of matched symbol inside a specific field

Input File

{"Hi","Hello","unix":["five","six"]}
{"Hi","Hello","unix":["five","six","seven","eight"]}

Output

{"Hi","Hello","unix":["five";"six"]}
{"Hi","Hello","unix":["five";"six";"seven";"eight"]}

Upvotes: 1

RavinderSingh13
RavinderSingh13

Reputation: 133428

If your Input_file is same as sample shown then following may help you in same.

sed 's/\([^[]*\)\([^,]*\),\(.*\)/\1\2;\3/g'   Input_file

Output will be as follows.

{"Hi","Hello","unix":["five";"six"]}

EDIT: Adding explanation also for same now, it should be only taken for explanation purposes, one should run above code only for getting the output.

sed 's/\([^[]*\)\([^,]*\),\(.*\)/\1\2;\3/g'   Input_file
s               ##is for substitution in sed.
\([^[]*\)       ##Creating the first memory hold which will have the contents from starting to before first occurrence of [ and will be obtained by 1 later in code.
\([^,]*\)       ##creating second memory hold which will have everything from [(till where it stopped yesterday) to first occurrence of ,
,               ##Putting , here in the line of Input_file.
\(.*\)          ##creating third memory hold which will have everything after ,(comma) to till end of current line.
/\1\2;\3/g      ##Now mentioning the memory hold by their number \1\2;\3/g so point to be noted here between \2 and \3 have out ;(semi colon) as per OP's request it needed semi colon in place of comma.

Upvotes: 2

zzxyz
zzxyz

Reputation: 2981

You should definitely use RavinderSingh13's answer instead of mine (it's less likely to break or exhibit unexpected behavior given very complex input) but here's a less robust answer that's a little easier to explain than his:

sed -r 's/(:\[.*),(.*\])/\1;\2/g' test

() is a capture group. You can see there are two in the search. In the replace, they are refered to as \1 and \2. This allows you to put chunks of your search back in the replace expression. -r keeps the ( and ) from needing to be escaped with a backslash. [ and ] are special and need to be escaped for literal interpretation. Oh, and you wanted .* not *. The * is a glob and is used in some places in bash and other shells, but not in regexes alone.

edit: and /g allows the replacement to happen multiple times.

Upvotes: 0

Related Questions