Search code examples
shellawksedkshcut

Can I change a cut command for a sed?


I'm writing a script, part of which is formatting a date value into one that is compatbile with SQL*Plus 8. The date format is:

20191115103845

And I need to change this string to

to_date('2019/11/15:10:38:45', 'yyyy/mm/dd:hh24:mi:ss')

And I use the cut tool:

funcion(){
        data=$1
        year=$(echo $data| cut -c1,2,3,4)
        month=$(echo $data | cut -c5,6)
        day=$(echo $data | cut -c7,8)
        hour=$(echo $data| cut -c9,10)
        min=$(echo $data| cut -c11,12)
        sec=$(echo $date | cut -c13,14)
        echo "to_date('"$year"/"$month"/"$day":"$hour":"$min":"$sec"', 'yyyy/mm/dd:hh24:mi:ss')"
}

funcion $data_to_format

(data_to_format=20191115103845)

My issue is that this takes some seconds, and i'm going to use this script for more than thousand files with 100+ dates each one. So I thought that maybe 'sed' command could be better for this. But I use a ksh88 (old ksh) and the sed does not have -E options and can't make it work.

Can anyone help me please with a old regexp sed solution?


Solution

  • Could you please try following, written and tested with shown samples in GNU awk.

    awk -v s1="\047" -v firstPart="to_date(" -v lastPart="yyyy/mm/dd:hh24:mi:ss" '
    {
      print firstPart s1 substr($0,1,4) "/" substr($0,5,2) "/" substr($0,7,2)":"\
            substr($0,9,2)":"substr($0,11,2)":"substr($0,13,2) s1 ", " s1\
            lastPart s1 ")"
    }
    ' Input_file
    

    Explanation:

    • -v s1="\047": Creating variable named s1 which has value as ' in it.
    • -v firstPart="to_date(": Creating variable firstPart which has string to_date( in it.
    • -v lastPart="yyyy/mm/dd:hh24:mi:ss": Creating variable lastPart which has string yyyy/mm/dd:hh24:mi:ss in it.
    • print: Using print function to print variables and values.
    • firstPart s1 substr($0,1,4) "/" substr($0,5,2) "/" substr($0,7,2)":"\ substr($0,9,2)":"substr($0,11,2)":"substr($0,13,2) s1 ", " s1\ lastPart s1 ")": Printing variables and sub-strings as per OP's requirements here.


    2nd solution: Adding a sed solution too here, using back reference capability of sed here.

    echo "20191115103845" |
    sed 's/\(....\)\(..\)\(..\)\(..\)\(..\)\(..\)/to_date(\x27\1\/\2\/\3:\4:\5:\6\x27, \x27yyyy\/mm\/dd:hh24:mi:ss\x27)/'
    

    OR Thanks to tripleee since \x27 may not be supported in few sed so adding another way of using ' inside sed code.

    echo "20191115103845" |
    sed 's/\(....\)\(..\)\(..\)\(..\)\(..\)\(..\)/to_date('"'"'\1\/\2\/\3:\4:\5:\6'"'"', '"'"'yyyy\/mm\/dd:hh24:mi:ss'"'"')/'