[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: print keep original format
From: |
lina |
Subject: |
Re: print keep original format |
Date: |
Thu, 26 May 2011 15:31:42 +0800 |
On Thu, May 26, 2011 at 1:35 PM, Bob Proulx <address@hidden> wrote:
> lina wrote:
>> I don't understand it so well.
>> can you help me with this issue?
>
> Okay. But please don't top-post. Please just quote the portion of
> the message that you want to talk about at that point.
>
>> Andreas Schwab wrote:
>> > lina writes:
>> >> if I wanna change $4 to B and print the line out
>> >> 497 FE HEM A 43 -12.543 18.254 -4.989 1.00 0.00
>
> You want to change "A" to "B" and those are the same size. But in
> general the sizes might change and you might replace one character
> with two or more. The problem for awk is then should it grow the
> field or replace spaces? Therefore what awk does is to recompute a
> new $0 output line based upon the OFS.
>
>> >> for a short awk script, such as
>> >> awk '{
>> >> if($2 == 497)
>> >> {
>> >> $5="B"
>> >> print $0
>> >> }
>> >> }' $1
>
> You must have left out a field in your data example. Because in your
> example 497 occurs in $1 not $2 and A occurs in $4 not $5. You must
> have another field there. I will insert an assumed X there to keep
> your field numbering and still have a working example.
It's my problem, I deleted the original $1 which was long and
disturbing infor. but forget to modified the awk script I posted
earlier.
>
>> >> but the output the space between them has gone.
>> >> jt turned out loss the format.
>> >> 497 FE HEM B 43 -12.543 18.254 -4.989 1.00 0.00
>
> Right. This is what Andreas meant when he said:
>
>> > Setting any field causes awk to recompute $0 based on the current value
>> > of OFS. If you want to avoid that you should operate on $0 directly.
>
>> > *Note (gawk) Changing Fields::
>
> The documentation on Changing Fields is also online on the web here:
>
> http://www.gnu.org/software/gawk/manual/gawk.html#Changing-Fields
>
> Since your OFS (output field separator) is a space character the $0 is
> written using each field and separates them using a single space.
>
> To avoid this you can edit $0 directly.
>
> sub(/ A /," B ",$0)
>
> That will look for space-A-space and replace it with space-B-space
> which is an extremely brute force approach to solving your problem but
> is illustrative of the type of thing that is meant when we say operate
> directly on $0.
>
> $ echo "X 497 FE HEM A 43 -12.543 18.254 -4.989 1.00 0.00" \
> | awk '{ if ($2 == 497) { sub(/ A /," B ",$0);print $0; } }'
> X 497 FE HEM B 43 -12.543 18.254 -4.989 1.00 0.00
>
> That might work okay for you but I worry that it would be too fragile.
> Instead I would explicitely write the format for the entire line.
>
> $ echo "X 497 FE HEM A 43 -12.543 18.254 -4.989 1.00 0.00" \
> | awk '{
> if ($2 == 497) {
> $5 = "B";
> printf("%s %3s %3s %4s %s %3s %11s %7s %7s %5s %5s\n",
> $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11);
> }
> }'
> X 497 FE HEM B 43 -12.543 18.254 -4.989 1.00 0.00
That's very nice of you. Sometimes I found it's not easy to set the
format of printf to aggre well with the former one.
Thanks again,
>
> By using printf with explicit field widths everything is formatted in
> the desired column. That is probably how I would do it.
>
> There are probably nicer ways to do it and perhaps someone will
> suggest something different.
>
> Bob
>
--
Best Regards,
lina