1

I am trying to replace the words between single quotes in a fil in bash, i tried with sed but its not working.

File contents

Haarlem -m 'foo' -n 'bar' aalsmeer > "goes to" -t 'value'
Roterdam -m 'foo2' -n 'bar2' amsterdam > "goes to" -t 'value'

expected output

Haarlem -m "verified" -n "verified" aalsmeer > "goes to" -t 'value'
Roterdam -m "verified" -n "verified" amsterdam > "goes to" -t 'value'

my below sed command is not working

sed 's/-m '*.*' -n '*.*'/-m "verified" -n "verified"/'
ajay
  • 59
  • 1
    Your regex is wrong - * is not a wildcard in regex, but a quantifier. – Panki Jun 03 '20 at 12:17
  • 1
    You also have a problem with the single quotes around the sed command interfering with those in the regular expression you are using to match the string to be replaced. – AdminBee Jun 03 '20 at 12:20

2 Answers2

4

You can use double quotes here:

$ sed "s/'[^']*'/\"verified\"/g" ip.txt
Haarlem -m "verified" -n "verified" aalsmeer > "goes to"
Roterdam -m "verified" -n "verified" amsterdam > "goes to" 
  • '[^']*' matches ' followed by non ' characters and again ' character
    • you cannot use '.*' because that will match from first ' to last ' in the input line
  • \"verified\" use "verified" as replacement string, double quote is escaped because it is being used inside double quotes

See also: https://mywiki.wooledge.org/Quotes and Why does my regular expression work in X but not in Y? (for difference between regex and wildcards)


The question was updated after above solution.

$ cat ip.txt
Haarlem -m 'foo' -n 'bar' aalsmeer > "goes to" -t 'value'
Roterdam -m 'foo2' -n 'bar2' amsterdam > "goes to" -t 'value'

$ sed -E "s/(-[mn] )'[^']*'/\1\"verified\"/g" ip.txt
Haarlem -m "verified" -n "verified" aalsmeer > "goes to" -t 'value'
Roterdam -m "verified" -n "verified" amsterdam > "goes to" -t 'value'
  • -[mn] will match either -m or -n
  • (-[mn] ) is a capture group, the content matched is reused in replacement section as \1

You can also use

sed -E "s/(-[^t] )'[^']*'/\1\"verified\"/g" ip.txt

to prevent only -t '..' from getting replaced and match all other single quoted patterns preceded by -<char> and a space

Sundeep
  • 12,008
  • I have added last part now -t par(which should be unchanged value), could u please check. – ajay Jun 03 '20 at 12:29
  • @ajay in future try to avoid changing the question and add all the details from the start itself.. I have updated the answer – Sundeep Jun 03 '20 at 12:33
  • @Sandeep - noted. just started using this forum, will make a note of it. – ajay Jun 03 '20 at 12:35
  • @ajay sure no problem, also I wish to clarify that editing the question to add more details is perfectly okay.. but in this case the problem statement itself changed, which is what you could try to avoid in future... – Sundeep Jun 03 '20 at 12:48
  • @Sandeep - Yes got the point, thanks. – ajay Jun 03 '20 at 12:50
0

I applaud the answer from Sundeep, but depending on how much you trust your data you can do it much simpler.

You only want to look at the first two occurrences thus you can simply call the same command twice. I choose the non-whitespace character assuming you have a whole word/numbers between quotes. The -E is just to be able to do extended regular expression.

test_file

Haarlem -m 'foo' -n 'bar' aalsmeer > "goes to"
Roterdam -m 'foo2' -n 'bar2' amsterdam > "goes to"
$ sed -E \
  -e "s/'\S+'/\"verified\"/" \
  -e "s/'\S+'/\"verifired\"/" test_file
#  
# Haarlem -m "verified" -n "verifired" aalsmeer > "goes to" -t 'value'
# Roterdam -m "verified" -n "verifired" amsterdam > "goes to" -t 'value'