Thursday, April 28, 2022

[SOLVED] How to update a multichracter delimited field in a file in bash?

Issue

I'm trying to match a certain field and update its data from a file delimited with multiple characters. I'm using this to create an imitation of SQL's UPDATE. This is part of a bigger project to create a mini DBMS with bash.

What I tried:

sed "s/\^\_\^/:/g" $file_path | cut -d: -f1 | grep -nw SAR | sed "s/\^\_\^/:/g" | cut -d: -f2 | sed -i "s/$match/$update/g"

My issue is I am unable to use sed -i to update only these specific columns found as you can't pipe into it.

The delimiter being used is : ^_^

Example of data file:

'EGP'^_^'Egypt'
'SAR'^_^'Europe'
'SAR'^_^'Europe'
'SAR'^_^'Europe'
'SAR'^_^'Europe'
'Europe'^_^'SAR'
'SAR'^_^'Europe'
'MYR'^_^'Malaysia'
'MYR'^_^'Malasia'

my $match can be SAR for example and $update would be USD

Expected change to data file

'EGP'^_^'Egypt'
'USD'^_^'Europe'
'USD'^_^'Europe'
'USD'^_^'Europe'
'USD'^_^'Europe'
'Europe'^_^'SAR'
'USD'^_^'Europe'
'MYR'^_^'Malaysia'
'MYR'^_^'Malasia'

If there is a different approach that is better, that is also welcome as I am fairly new to bash scripting.


Solution

Better to use awk here:

awk -v s="'SAR'" -v q="'USD'" -F'\\^_\\^' -v OFS='^_^' '$1==s {$1=q} 1' file

'EGP'^_^'Egypt'
'USD'^_^'Europe'
'USD'^_^'Europe'
'USD'^_^'Europe'
'USD'^_^'Europe'
'Europe'^_^'SAR'
'USD'^_^'Europe'
'MYR'^_^'Malaysia'
'MYR'^_^'Malasia'

Explanation:

  • -v s="'SAR'" sets command line variable s='SAR'
  • -v q="'USD'" sets command line variable s='USD'
  • -F '\\^_\\^' sets input field separator as ^_^. We need to escape ^ as that is a special regex meta character and we need to double escape it because we're using it in a string that is later converted to a regexp (field separator).
  • -v OFS='^_^' sets output field separator to ^_^
  • $1 == s compares first field to 'SAR'
  • $1 = q sets $1 to variable 'USD'


Answered By - anubhava
Answer Checked By - Marie Seifert (WPSolving Admin)