String Manipulation

Hi,
I have a file in the following format

123|shanwer|15DEC2010|bgbh|okok|16JAN3000|okok|

I want the following to be in following format

123|shanwer|12\15\2010|bgbh|okok|01\16\3000|okok|

SED/PERL/AWK Gurus
could you please help me with this?

Thanks
Shankar

Try this,

awk -F"|" 'BEGIN{a["JAN"]="01"
a["FEB"]="02"
a["MAR"]="03"
a["APR"]="04"
a["MAY"]="05"
a["JUN"]="06"
a["JUL"]="07"
a["AUG"]="08"
a["SEP"]="09"
a["OCT"]="10"
a["NOV"]="11"
a["DEC"]="12" }
{for(i=1;i<=NF;i++) {if($i ~ /[0-9].[A-Z]..[0-9].../){printf a[substr($i,3,3)]"\\"substr($i,1,2)"\\"substr($i,6) FS}else{printf $i FS}}printf "\n" }' inputfile
3 Likes
perl -i -pe '
BEGIN{
   %h=qw(
  JAN 01
  FEB 02
  MAR 03
  APR 04
  MAY 05
  JUN 06
  JUL 07
  AUG 08
  SEP 09
  OCT 10
  NOV 11
  DEC 12
   );} foreach  $k (keys %h){ s/(\d+)$k(\d+)/$h{$k}\\$1\\$2/ };' infile
1 Like

With GNU date (if year<=2038) (not so efficient):

 awk -F\| '{for(i=3;i<=6;i+=3)"date -d"$i" +\"%m\\%d\\%Y\""|getline $i}1' OFS=\| infile
while IFS=\| read f1 f2 f3 f4 f5 f6 f7 f8
do
   echo "$f1|$f2|$(date -d $f3 +'%m\%d\%Y')|$f4|$f5|$(date -d $f6 +'%m\%d\%Y')|$f7|$f8"
done

Hi,

Another solution:

$ cat script.awk
BEGIN {
    m["JAN"] = "01"
    m["FEB"] = "02"
    m["MAR"] = "03"
    m["APR"] = "04"
    m["MAY"] = "05"
    m["JUN"] = "06"
    m["JUL"] = "07"
    m["AUG"] = "08"
    m["SEP"] = "09"
    m["OCT"] = "10"
    m["NOV"] = "11"
    m["DEC"] = "12"

    IGNORECASE = 1
    FS = "|"
}

{
    # Dates are fields n�3 and n�6.

    # Get day (first two characters), month (next three characters) and
    # year (last four characters).
    day = substr($3, 0, 2)
    month = substr($3, 3, 3)
    year = substr($3, 6)
    $3 = m[month] "\\" day "\\" year

    day = substr($6, 0, 2)
    month = substr($6, 3, 3)
    year = substr($6, 6)
    $6 = m[month] "\\" day "\\" year

    OFS = "|"
    print
}

$ awk -f script.awk infile

Regards,
Birei

1 Like
# ./justdoit infile
123|shanwer|12\15\2010|bgbh|okok|01\16\3000|okok|
## justdoit ##
x="JAN=01 FEB=02 MAR=03 APR=04 MAY=05 JUN=06 JUL=07 AUG=08 SEP=09 OCT=10 NOV=11 DEC=12"
for i in $(echo "$x" | sed 's/=[0-9]*//g') ; do
 y=$(sed "s/.*\($i\).*/\1/" infile); y1=$(echo "$x"| sed "s/.*$i=\([0-9]*\).*/\1/")
 sed -i "s/\(.*\)|\(.*\)$y\(.*\)|\(.*\)/\1|$y1\\\\\2\\\\\3\4|/" infile 2>/dev/null
done ;  more infile

regards
ygemici

1 Like

Thanks for you help!!!
I tried with your code,
however it does not changes all the requred substrings in one go i had to run the same scrip twice to get desired results.
My text file was 1,000,000 + records and this scrip is not capable of produting anothe file, it acts on same file. I am new to this coading please bear me,.

awk -F\| 'BEGIN{split("JAN FEB MAR APR MAI JUN JUL AUG SEP OCT NOV DEC",A," "); while (++i in A)M[A]=i; D[3]; D[6]}
         {for(i in D)$i=sprintf("%02d\\%s\\%s",M[substr($i,3,3)],substr($i,1,2),substr($i,6))}1' OFS=\|

You must create a filelist..

## justdoit ##
ls -1 desiredfiles | 
while read -r infile ; do
 # backup
 cp $infile $infile_bck
 # process
 x="JAN=01 FEB=02 MAR=03 APR=04 MAY=05 JUN=06 JUL=07 AUG=08 SEP=09 OCT=10 NOV=11 DEC=12"
 for i in $(echo "$x" | sed 's/=[0-9]*//g') ; do
  y=$(sed "s/.*\($i\).*/\1/" $infile); y1=$(echo "$x"| sed "s/.*$i=\([0-9]*\).*/\1/")
  sed -i "s/\(.*\)|\(.*\)$y\(.*\)|\(.*\)/\1|$y1\\\\\2\\\\\3\4|/g" $infile 2>/dev/null
 done ;  more $infile
done