# How to identify delimiter to find and replace a string with sed?

**URL:** <https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562>\
**Category:** UNIX for Beginners Q & A\
**Created:** [October 29, 2019, 4:23pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562 "2019-10-29T16:23:01Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![duke0001](https://community.unix.com/letter_avatar/duke0001/32/5_5575768a8748004e209b776fc1b2916d.png) [@duke0001](https://community.unix.com/u/duke0001)\
**Post date:** [October 29, 2019, 4:23pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/1 "2019-10-29T16:23:01Z")

</div>

I need to find and replace a date format in a SQL script with `sed` . The original lines are like this:

```nohighlight
       ep.begin_date, ep.end_date, ep.facility_code,
       AND ep.begin_date <= '01-JUL-2019'
                     ep.begin_date, ep.end_date, ep.facility_code,
       AND ep.begin_date <= '01-JUL-2019'
                     ep.begin_date, ep.end_date, ep.facility_code,
       AND ep.begin_date <= '01-JUL-2019'

```

Then I want to replace '01-JUL-2019' with variable which real value is '01-OCT-2019'. After replacement, the line in file should be like this:  
AND ep.begin\_date \<= '01-OCT-2019'. I am not good at how to use `sed` to identify delimiter or separator and help `sed` to find right part of this string and replace it with right value. Please help with your code. My testing code is ugly so that I do not post them. I would like to learn from all of you. Thanks for help.

---

<div class="post-metadata">

**Author:** ![RudiC](https://community.unix.com/letter_avatar/rudic/32/5_5575768a8748004e209b776fc1b2916d.png) [@RudiC](https://community.unix.com/u/RudiC)\
**Post date:** [October 29, 2019, 5:27pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/2 "2019-10-29T17:27:00Z")

</div>

How specific the date regex has to be? Is it OK to match 31-FEB? Any condidtions for the year, e.g. only 20xx, or 19xx as well? Does your `sed` handle EREs? Try

```nohighlight
NEWDATE=01-OCT-2019
sed -r "s/[0-3][0-9]-($(locale abmon | tr 'a-z;' 'A-Z|'))-[12][09][0-9]{2}/$NEWDATE/" file
       ep.begin_date, ep.end_date, ep.facility_code,
       AND ep.begin_date <= '01-OCT-2019'
                     ep.begin_date, ep.end_date, ep.facility_code,
       AND ep.begin_date <= '01-OCT-2019'
                     ep.begin_date, ep.end_date, ep.facility_code,
       AND ep.begin_date <= '01-OCT-2019'

```

---

<div class="post-metadata">

**Author:** ![duke0001](https://community.unix.com/letter_avatar/duke0001/32/5_5575768a8748004e209b776fc1b2916d.png) [@duke0001](https://community.unix.com/u/duke0001)\
**Post date:** [October 30, 2019, 11:08am UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/3 "2019-10-30T11:08:45Z")

</div>

RudiC:

Thanks for your questions and advice. My Unix is Solaris 10. It seems `sed` do not support EREs. Please see following output. As for date regex is concerned, this format was created by some other people and has been in production for years. I could not change it at this moment. So the best expression will still be like '01-MON-20XX' or '31-MON-20XX'. These dates are government fiscal quarter begin date and end date. It is in SQL statement. I want to use shell script to automate the change to new quarter begin date and end date for data process and report generation. You are absolutely right. $NEWDATA is variable which is queried from database and put with `sed` to replace old date. Here is output:

```nohighlight
/home/oracle> sed -r "s/[0-3][0-9]-($(locale abmon | tr 'a-z;' 'A-Z|'))-[12][09][0-9]{2}/"'01-OCT-2019'"/" test4.txt
sed: illegal option -- r

/home/oracle> sed -E "s/[0-3][0-9]-($(locale abmon | tr 'a-z;' 'A-Z|'))-[12][09][0-9]{2}/"'01-OCT-2019'"/" test4.txt
sed: illegal option -- E

/home/oracle> sed -e "s/[0-3][0-9]-($(locale abmon | tr 'a-z;' 'A-Z|'))-[12][09][0-9]{2}/"'01-OCT-2019'"/" test4.txt
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'

```

Now question is: based on Solaris 10, how can `sed` handle the extended regular expressions? Please give me some idea. Thanks.

---

<div class="post-metadata">

**Author:** ![vgersh99](https://community.unix.com/user_avatar/community.unix.com/vgersh99/32/14851_2.png) [@vgersh99](https://community.unix.com/u/vgersh99)\
**Post date:** [October 30, 2019, 11:19am UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/4 "2019-10-30T11:19:30Z")

</div>

how about:

```nohighlight
/home/oracle> sed -e "s/[0-3][0-9]-($(locale abmon | tr 'a-z;' 'A-Z|'))-[12][09][0-9][0-9]/"'01-OCT-2019'"/" test4.txt

```

---

<div class="post-metadata">

**Author:** ![duke0001](https://community.unix.com/letter_avatar/duke0001/32/5_5575768a8748004e209b776fc1b2916d.png) [@duke0001](https://community.unix.com/u/duke0001)\
**Post date:** [October 30, 2019, 12:13pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/5 "2019-10-30T12:13:59Z")

</div>

vgersh99:

Thanks for input, here is the output

```nohighlight
/home/oracle/> sed -e "s/[0-3][0-9]-($(locale abmon | tr 'a-z;' 'A-Z|'))-[12][09][0-9][0-9]/"'01-OCT-2019'"/" test4.txt
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'

```

---

<div class="post-metadata">

**Author:** ![RudiC](https://community.unix.com/letter_avatar/rudic/32/5_5575768a8748004e209b776fc1b2916d.png) [@RudiC](https://community.unix.com/u/RudiC)\
**Post date:** [October 30, 2019, 12:41pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/6 "2019-10-30T12:41:50Z")

</div>

OK, then, try to write the months verbatim explicitly and escape parentheses, pipes, and braces:

```nohighlight
sed "s/[0-3][0-9]-\(JUN\|JUL\|AUG\)-[12][09][0-9]\{2\}/$NEWDATE/" file

```

---

<div class="post-metadata">

**Author:** ![duke0001](https://community.unix.com/letter_avatar/duke0001/32/5_5575768a8748004e209b776fc1b2916d.png) [@duke0001](https://community.unix.com/u/duke0001)\
**Post date:** [October 30, 2019, 3:35pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/7 "2019-10-30T15:35:43Z")

</div>

RudiC:

To write months verbatim and escape, it didn't work either. I need `sed` identify months because 4 quarters have 4 different begin date and 4 end date. Hard code will not work. I tried something. Please see all output below. Here, $NEWDATE=01-OCT-2019.

```nohighlight
/home/oracle> sed "s/[0-3][0-9]-\(JUN\|JUL\|AUG\)-[12][09][0-9]\{2\}/$NEWDATE/" test4.txt
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'

/home/oracle/> sed "s/[0-3][0-9]\-[a-zA-Z]{3}\-[12][09][0-9]\{2\}/$NEWDATE/" test4.txt
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'

```

---

<div class="post-metadata">

**Author:** ![RudiC](https://community.unix.com/letter_avatar/rudic/32/5_5575768a8748004e209b776fc1b2916d.png) [@RudiC](https://community.unix.com/u/RudiC)\
**Post date:** [October 30, 2019, 3:38pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/8 "2019-10-30T15:38:34Z")

</div>

Does your OS provide other `sed` versions?

For debugging, try to restrict yourself to match the months only. You may want to apply vgersh99's proposal as well to get rid of the `{2}` .

---

<div class="post-metadata">

**Author:** ![duke0001](https://community.unix.com/letter_avatar/duke0001/32/5_5575768a8748004e209b776fc1b2916d.png) [@duke0001](https://community.unix.com/u/duke0001)\
**Post date:** [October 30, 2019, 4:25pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/9 "2019-10-30T16:25:11Z")

</div>

RudiC:

Thanks for suggestion, I tried. It output the same result. I know the Date format in our SQL script is not configured well. But I cannot make change at this time. It will cause many changes. On our Solaris 10, we have `/usr/xpg4/bib/sed` , can this `sed` work?  
These two use vgersh99's proposal and without {2}

```nohighlight
/home/oracle> sed -e "s/[0-3][0-9]-($(locale abmon | tr 'a-z;' 'A-Z|'))-[12][09][0-9][0-9]/$NEWDATE/" test4.txt
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'

/home/oracle> sed "s/[0-3][0-9]\-[a-zA-Z]{3}\-[12][09][0-9][0-9]/$NEWDATE/" test4.txt
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'

```

I am working on how to restrict to match the month. Thanks for your help.

---

<div class="post-metadata">

**Author:** ![RudiC](https://community.unix.com/letter_avatar/rudic/32/5_5575768a8748004e209b776fc1b2916d.png) [@RudiC](https://community.unix.com/u/RudiC)\
**Post date:** [October 30, 2019, 4:29pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/10 "2019-10-30T16:29:28Z")

</div>

You'll have to debug stepwise. What be the result of

```nohighlight
sed "s/\(JUN\|JUL\|AUG\)/XXXX/" file

```

?  
And yes, try `/usr/xpg4/bin/sed` (NOT `bib` !).

---

<div class="post-metadata">

**Author:** ![duke0001](https://community.unix.com/letter_avatar/duke0001/32/5_5575768a8748004e209b776fc1b2916d.png) [@duke0001](https://community.unix.com/u/duke0001)\
**Post date:** [October 30, 2019, 5:18pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/11 "2019-10-30T17:18:48Z")

</div>

RudiC:

Thanks for new input. I tried and got this output,

```nohighlight
/home/oracle/>/usr/xpg4/bin/sed "s/\(JUN\|JUL\|AUG\)/$NEWDATE" test4.txt
sed: command garbled: s/\(JUN\|JUL\|AUG\)/01-OCT-2019

```

Now the problem is that `sed` cannot find or match the month. If `sed` match the old date, then new date will replace it. I will continue to debug step by step. Thanks a lot.

---

<div class="post-metadata">

**Author:** ![RudiC](https://community.unix.com/letter_avatar/rudic/32/5_5575768a8748004e209b776fc1b2916d.png) [@RudiC](https://community.unix.com/u/RudiC)\
**Post date:** [October 30, 2019, 6:30pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/12 "2019-10-30T18:30:12Z")

</div>

You're missing a ` / ` at the end of your ` s ` command:

```nohighlight
/home/oracle/>/usr/xpg4/bin/sed "s/\(JUN\|JUL\|AUG\)/$NEWDATE/" test4.txt

```

---

<div class="post-metadata">

**Author:** ![duke0001](https://community.unix.com/letter_avatar/duke0001/32/5_5575768a8748004e209b776fc1b2916d.png) [@duke0001](https://community.unix.com/u/duke0001)\
**Post date:** [October 31, 2019, 10:01am UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/13 "2019-10-31T10:01:44Z")

</div>

RudiC:

Yes. I missed a `/` and tested again. The result is still not working. It seems that `sed` cannot find `MON` in lines. This part- `s/\(JUN\|JUL\|AUG\)` is not functioning. see output,

```nohighlight
/home/oracle> /usr/xpg4/bin/sed "s/\(JUN\|JUL\|AUG\)/$NEWDATE/" test4.txt
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'

```

Thanks.

---

<div class="post-metadata">

**Author:** ![RudiC](https://community.unix.com/letter_avatar/rudic/32/5_5575768a8748004e209b776fc1b2916d.png) [@RudiC](https://community.unix.com/u/RudiC)\
**Post date:** [October 31, 2019, 10:19am UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/14 "2019-10-31T10:19:34Z")

</div>

Didn't you say you're doing a step by step debug?  
Try

```nohighlight
sed "s/\(JUL\)/XXX/" file

```

Read your `sed` version's man page!

---

<div class="post-metadata">

**Author:** ![duke0001](https://community.unix.com/letter_avatar/duke0001/32/5_5575768a8748004e209b776fc1b2916d.png) [@duke0001](https://community.unix.com/u/duke0001)\
**Post date:** [October 31, 2019, 11:26am UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/15 "2019-10-31T11:26:13Z")

</div>

RudiC:

Thanks. I debugged as this, this time, `sed` found the specific `MON` and replace it with whole value of $NEWDATE. But the `DD` and `YYYY` are not searched and replaced. I put `DD` in search, then the command doesn't work again. Here is output,

```nohighlight
/home/oracle> /usr/xpg4/bin/sed "s/\(JUL\)/$NEWDATE/" test4.txt
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-01-OCT-2019-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-01-OCT-2019-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-01-OCT-2019-2019'

/home/oracle> /usr/xpg4/bin/sed "s/[0-3][0-9]\(JUL\)/$NEWDATE/" test4.txt
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'
       ep.begin_date, ep.end_date, ep.facility_code,
AND ep.begin_date <= '01-JUL-2019'

```

I will continue debug `DD` and `YYYY`  
Thanks

---

<div class="post-metadata">

**Author:** ![duke0001](https://community.unix.com/letter_avatar/duke0001/32/5_5575768a8748004e209b776fc1b2916d.png) [@duke0001](https://community.unix.com/u/duke0001)\
**Post date:** [October 31, 2019, 12:48pm UTC](https://community.unix.com/t/how-to-identify-delimiter-to-find-and-replace-a-string-with-sed/376562/16 "2019-10-31T12:48:08Z")

</div>

RudiC:

I have tried different ways. it didn't work. So I will take stupid way to do this work. I will pick up `$OLDDATE ` and `$NEWDATE` two variables from database. Then:

```nohighlight
/usr/xpg4/bin/sed "s/$OLDDATE/$NEWDATE/" test4.txt > test4_output.txt

```

It sounds working. Then I go to next step. Thanks anyway for your help and advice. I will continue to learn from this forum.
