Hi Experts,
I have binary files contain an ID Line as:
:
:
$Header: FNDSCMON.fmb 115.6 2000/01/11 10:26:10 pkm ship$
:
:
where the ID Line format is:
$Header: <File_Name> <Version> <Last_update_date_time> pkm ship$
In this Example:
File_Name = FNDSCMON.fmb
Version = 115.6
Last_update_date_time = 2000/01/11 10:26:10
I want to write a script to update the ID Line as:
File_Name = the file name
Version = old_version + 0.1
Last_update_date_time = current date_time
so, the new ID line should be show as:
:
:
$Header: <the file name> <old_version + 0.1> <current date_time> pkm ship$
:
:
Can anyone help?
Thanks!
Victor Cheung
This should do the job:
#!/bin/sh
curr_dat=`date "+%Y\/%d\/%m"`
curr_time=`date "+%H:%M:%S"`
awk -v ver="old_version + 0.1" -v dat=$curr_dat -v t=$curr_time '
/^\$Header:/{$2=FILENAME;$3=ver;$4=dat;$5=t}1
' file
Regards
Hi Frank,
Sorry, I think I have uncompleted mentions of my question, here is the complete one, can you please help? :
I have binary files contain an ID Line as:
:
:
$Header: FNDSCMON.fmb 115.6 2000/01/11 10:26:10 pkm ship$
:
:
where the ID Line format is:
$Header: <File_Name> <Version> <Last_update_date_time> pkm ship$
In this Example:
File_Name = FNDSCMON.fmb
Version = 115.6
Last_update_date_time = 2000/01/11 10:26:10
I want to write a script to update the ID Line as:
File_Name = the file name
Version = version + 0.1
Last_update_date_time = current date_time
so, the new ID line should be show as:
:
:
$Header: <the file name> <version + 0.1> <current date_time> pkm ship$
:
:
The line starts with "$Header:" and ends with "pkm ship$"
The new line length have to be kept as same as the old line length (the whitespaces is adjustable)
perl should be used for the replacment action (The files I want to change are binary files, using other command, such as, sed will make the file unusable)
Can you help how to write the script?
Many Thanks!
Victor Cheung
In that case you have to provide more information, what is the exact length of the fields, beginning in what position?
Regards
Hi Frank,
The exact length between the Start Pattern,$Header:, and the End Pattern,pkm ship$, is fixed to 80 characters,
e.g.1:
$Header: FNDSCMON.fmb 115.6 2000/01/11 10:26:10........................pkm ship$
could be changed as :
$Header: FNDSCMON.fmb 115.7 2008/04/21 13:29:09........................pkm ship$
or, e.g.2:
Other Word $Header: FNDSCMON.fmb 115.6 2000/01/11 10:26:10........................pkm ship$
could be changed as :
Other Word $Header: FNDSCMON.fmb 115.7 2008/04/21 15:36:50........................pkm ship$
p.s. please replace the .... as whitespaces, multi whitespaces will be trunced when posted to this forum, so I use .... instead.
Many Thanks!
Victor Cheung
Try this:
#!/bin/sh
curr_dat=`date "+%Y\/%m\/%d"`
curr_time=`date "+%H:%M:%S"`
awk -v dat=$curr_dat -v t=$curr_time -v name="old_version" -v ver="0.1" '
/^\$Header:/{
$2=sprintf("%-12s",name)
$3=sprintf("%-5s",ver)
$4=sprintf("%-10s",dat)
$5=sprintf("%-31s",t)
}1
' file
Regards
era
April 21, 2008, 3:18am
7
perl -pe 's!(\$Header: \S+ )(\d+\.\d+) (\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2})( +pkm ship\$)\n!
my ($head, $ver, $date, $tail) = ($1, $2, $3, $4);
my @now = gmtime();
sprintf "%s %3.1f %04i/%02i/%02i %02i:%02i:%02i%s\n",
$head, $ver+0.1, $now[5]+1900, $now[4]+1, $now[3], $now[2], $now[1], $now[0], $tail !e' file
... assuming you want the date stamp in GMT (you probably do, even if you think you don't).
The version will monotonously grow by 0.1 for each update; so after 115.9 you get 116.0, 116.1, etc. Hope you won't need to go beyond 999.9 because this code won't handle that (without wrecking the fixed-length constraint).
I don't have anything really to test this on, but report back if it doesn't work.
time=`date '+%m/%d/%y %H:%M:%S`
nawk -v t="$time" '{
if ($1 ~ /\$Header:/ )
printf("%s %s %f %s pkm ship$\n",$1,$2,$3+0.1,t)
else
print
}' filename
summer_cherry,
The OP also wants replace the filename and version and also to keeps the exact length of a record.
Regards.
era
April 21, 2008, 5:34am
10
Also note that the $Header keyword is not necessarily at start of line, or the first field.
I was under the impression that the file name should stay.
Hi Era,
Assume that I have a file VT100.fmm with content:
$Header: FNDSCMON.fmb 115.6 2000/01/11 10:26:10........................pkm ship$
Other Word $Header: FNDSCMON.fmb 115.6 2000/01/11 10:26:10........................pkm ship$
$Header: FNDSCMON.fmb 115.6 2000/01/11 10:26:10........................pkm ship$
and I convert it with:
perl -pe 's!(\$Header: \S+ )(\d+\.\d+) (\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2})( +pkm ship\$)\n!
my ($head, $ver, $date, $tail) = ($1, $2, $3, $4);
my @now = gmtime();
sprintf "%s %3.1f %04i/%02i/%02i %02i:%02i:%02i%s\n",
$head, $ver+0.1, $now[5]+1900, $now[4]+1, $now[3], $now[2], $now[1], $now[0], $tail !e' VT100.fmm
and I view the file using vi, but the lines were not changed, can you please help?
Thanks!
Victor Cheung
era:
Also note that the $Header keyword is not necessarily at start of line, or the first field.
I was under the impression that the file name should stay.
If the $Header keyword is not at the start of line:
#!/bin/sh
curr_dat=`date "+%Y\/%m\/%d"`
curr_time=`date "+%H:%M:%S"`
awk -v dat=$curr_dat -v t=$curr_time -v name="old_version" -v ver="0.1" '
/\$Header:/{
$2=sprintf("%-12s",name)
$3=sprintf("%-5s",ver)
$4=sprintf("%-10s",dat)
$5=sprintf("%-31s",t)
}1
' file
Regards
era
April 21, 2008, 6:16am
13
If it's not even $1, the field numbers are wrong, too. Up in comment #5 victorcheung writes:
Anyway, awk is not necessarily very robust when it comes to handling binary files, whereas Perl supposedly is.
Hi Era,
Thank you very much, it works!!
Hi Frank and Summer,
Thank you for your help!! But the perl works for binary file.
Thanks again!!
Victor Cheung