File manipulation place 0 before the number using sed

I'm new with sed, and i am really confused with slashes, backslashes, parentheses, I've tried reading some beginner's guide, but still trouble fixing this problem, do you have any tips where or what to read to learn more about sed? can you also help me with my problem?

Note: I was tasked to use sed on this.

Sample file:

upctm,pmdw_bip,pmdw_bip_mnt_35-FOLDistAutoRpt,Oct 7 2019 4:45 AM,Oct 7 2019 4:45 AM,1,1,Oct 6 2019 12:00 AM,Ended OK,3ppnc
upctm,pmdw_ddm,pmdw_ddm_dum_01-StartProjDCSDemand,Oct 17 2019 4:02 AM,Oct 17 2019 4:02 AM,3,1,Oct 16 2019 12:00 AM,Ended OK,3pqgq

I need to add 0 if the number in day is 1 only (ex. Oct 7 2019 to Oct 07 2019).

I've tried to sed, but the Oct 17 was changed to Oct 017

sed 's/Oct /Oct 0/g' sample_file.txt

Output:
upctm,pmdw_bip,pmdw_bip_mnt_35-FOLDistAutoRpt,Oct 07 2019 4:45 AM,Oct 07 2019 4:45 AM,1,1,Oct 06 2019 12:00 AM,Ended OK,3ppnc
upctm,pmdw_ddm,pmdw_ddm_dum_01-StartProjDCSDemand,Oct 017 2019 4:02 AM,Oct 017 2019 4:02 AM,3,1,Oct 016 2019 12:00 AM,Ended OK,3pqgq

Thank you in advance

Hello akopocpoypoy,

Could you please try following.

awk '
{
  while(match($0,/Oct [0-9]+/)){
    val=sprintf("%s %02d",substr($0,RSTART,4),substr($0,RSTART+3,RLENGTH-3))
    sub(/Oct [0-9]+/,val)
  }
}
1
'  Input_file

Thanks,
R. Singh

1 Like

You must capture a digit that is followed by a space. Because all the matched part is substituted, you must put it back with \1 and \2 that refer to the 1st and 2nd \(capture group\).

sed 's/\(Oct\) \([1-9]\) /\1 0\2 /g' sample_file.txt

Because I put the Oct in a group, you can easily generalize it, to match all 3-letter month names: \([A-Z][a-z][a-z]\)

1 Like

In case there are other occurrences of three letters followed by a space and a digit, you might want to narrow down the search pattern to the locale months:

sed -r "s/($(locale abmon | tr ';' '|')) ([[:digit:]] )/\1 0\2/g" file

Be aware that you need sed to recognize / handle EREs for this simple tr approach.

Hello akopocpoypoy,

Or adding 1 more approach where no need to hard code string again and again, simply keep a string into a variable Oct in this case and need not to change anything in code.

awk -v var="Oct" '
{
  while(match($0,var" [0-9]+")){
    val=sprintf("%s %02d",substr($0,RSTART,4),substr($0,RSTART+3,RLENGTH-3))
    sub(var " [0-9]+",val)
  }
}
1
'   Input_file

Thanks,
R. Singh