-1

I am trying to work on a script where it is a *(star) delimited file has a multiple lines starts with DTP. I want to substring the date part and compare with today's date. If it is older than today, I want to replace with today's date. Here is an example.

$ cat temp.txt
RTG*888*TD8*20180201-20180201~
TWW*888*RD8*20180201-20180201~
RTG*888*TD8*20180201-20180201~
KCG*888*TD8*20180201-20180201~

I want the output as below by changing date. Please help. I am looking for UNIX script to make it work for all files present in that directory

RTG*888*TD8*20190424-20190424~
TWW*888*RD8*20180201-20180201~
RTG*888*TD8*20190424-20190424~
KCG*888*TD8*20180201-20180201~

Thanks in advance

oguz ismail
  • 1
  • 16
  • 47
  • 69
Shan
  • 11
  • 1
  • 7
  • 1
    What have you tried so far? And, why are dates in `TWW*888*RD8*20180201-20180201~` and `KCG*888*TD8*20180201-20180201~` not replaced? – oguz ismail Apr 24 '19 at 04:13
  • 1
    I am new bee to unix .So i couldn't able to prepare a script . The line where starts with RTG only should get replaced with current date. – Shan Apr 24 '19 at 04:45
  • It is hard to say what is wrong with your code because you did not provide it or the errors you encountered. Also see [How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). – jww Apr 24 '19 at 06:01

2 Answers2

0

Considering that your files will not have future dates(as per your samples looks like that), if this is the case then try.

awk -v dat="$(date +%Y%m%d)" '
BEGIN{
  FS=OFS="*"
}
{
  split($4,array,"[-~]")
  if(array[1]!=dat){
    array[1]=dat
  }
  if(array[2]!=dat){
    array[2]=dat
  }
  $4=array[1]"-"array[2]"~"
}
1'   Input_file
RavinderSingh13
  • 130,504
  • 14
  • 57
  • 93
0

The following will work on systems with Bash and GNU's date utility. Let's do a simple script using "while read" loop:

# read the file line by line with fields separated by *
while IFS='*' read -r str1 num str2 date; do
    # if the first field is RTG
    if [ "$str1" = "RTG" ]; then
        # then substitute date with current date string
        curdate=$(date +%Y%m%d)
        date="${curdate}-${curdate}~"
    fi
     # print the output
    printf "%s*%s*%s*%s\n" "$str1" "$num" "$str2" "$date"
# in while read loops - the input file is 
# redirected to standard input on the end
done < file.txt

Could you please modify the script you provided to work for all files in directory. That would be very helpful for me .

# for all entries in current directory (uses bash globulation settings(!))
for file in *; do
   # check if it's a file
   if [ ! -f "$file" ]; then
        # if not, next entry
        continue;
   fi

   # run the script
   while IFS='*' read -r str1 num str2 date; do
        if [ "$str1" = "RTG" ]; then
            curdate=$(date +%Y%m%d)
            date="${curdate}-${curdate}~"
        fi
        printf "%s*%s*%s*%s\n" "$str1" "$num" "$str2" "$date"
    done < "$file"

done
KamilCuk
  • 120,984
  • 8
  • 59
  • 111
  • Bingo...! Its Worked as expected @ Kamil Cuk.. But how to execute the script for all the files present in particular directory Kindly help. – Shan Apr 25 '19 at 12:00
  • for example: `for file in particulardirectory/*; do while IFS='*' read ....... done < "$file"; done`. or `IFS='\n' files=($(find particulardirectory -type f)); for file in "${files[@]}"; do while ..... done <"$file"; done` – KamilCuk Apr 25 '19 at 18:11
  • Hey kamil, If i want to replace the date part to current date minus(-) 15 days without comparing the existing date in file .How to do that. can you please help me modifyng this – Shan May 02 '19 at 05:15
  • So follow up to reading the documentation, specify [man date](http://man7.org/linux/man-pages/man1/date.1.html). I think `date '--date=-15days'` could print date minus 15 dates. Please read [What should I do when someone answers my question?](https://stackoverflow.com/help/someone-answers) – KamilCuk May 02 '19 at 05:32
  • Getting an error below date: illegal option -- - Usage: date [-u] [+Field Descriptors] – Shan May 02 '19 at 05:38
  • As i am tried , i could not able to modify the script to work it for all files present in directory .. .I kindly request you help me out to modify the script you provided.Please – Shan May 02 '19 at 05:49
  • Are you on IBM? Mac OS? You tagged `linux`. – KamilCuk May 02 '19 at 06:29
  • I am using putty in windows server @kamil Cuk – Shan May 02 '19 at 06:46
  • AIX is not linux. You should remove that tag from you question and tag AIX. [linux date](http://man7.org/linux/man-pages/man1/date.1.html) is different from [AIX date](https://www.ibm.com/support/knowledgecenter/ssw_aix_71/com.ibm.aix.cmds2/date.htm) and all other utilities are different too. I have no experience in AIX. Do you have bash shell or some other shell? Try `echo $BASH_VERSION` or similar. You could get `date +%s` to get seconds, substract `15 * 24 * 60 * 60` seconds from it and then display the date using proper format. Or you could install GNU date utility. – KamilCuk May 02 '19 at 07:23
  • Do you have `awk`? This is possible in `awk` and will work way faster, however I am not enough fluent in it to do it. I would rather advise to ask a new question, with proper tags and show what you've done and tried. – KamilCuk May 02 '19 at 07:28
  • I will check on it . Could you please help on second part that i could not able to modify the script to work it for all files present in directory .. .I kindly request you help me out to modify the script you provided – Shan May 02 '19 at 07:28
  • This is a separate question [bash-script-to-execute-command-on-all-files-in-a-directory](https://stackoverflow.com/questions/10523415/bash-script-to-execute-command-on-all-files-in-a-directory) – KamilCuk May 02 '19 at 07:29
  • I am very new to this Unix shell scripting so i couldn't able to understand as much in link. Could you please modify the script you provided to work for all files in directory. That would be very helpful for me . – Shan May 02 '19 at 08:17
  • The script provided is just displaying manipulated data of all files content in black screen. How to write it back to their respective individual files – Shan May 03 '19 at 03:35
  • Just redirect `while` output, the same you redirect input. You can `done <"$file" | sponge "$file"` or like `done < "$file" > "/tmp/some_temp_file" ; mv /tmp/some_temp_file "$file"`. Don't do `< "$file" > "$file"`, it will not work and you will loose your files (you can't read and write to the same file at the same time...). Ach, I guess you don't have [sponge](https://linux.die.net/man/1/sponge), so use a temporary file and `mv`. – KamilCuk May 03 '19 at 08:27