PHWinfo banniere

Titres
PORTAIL ANNUAIRE ARTICLES COMPARATEUR HÉBERGEURS DEVIS FORUMS RÉDUCTEUR D'URL
Précédent   PHWinfo > Forums Hébergement > Forum Serveur - Sécurité et techniques > comp.unix.shell > awk !print$x
S'inscrire FAQ Membres Recherche Messages du jour Marquer les forums comme lus
comp.unix.shell Using and programming the Unix shell.

awk !print$x

Réponse
 
LinkBack Outils de la discussion
Vieux 23/07/2007, 05h15   #1
Faeandar
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut awk !print$x

I've got a multi pipe command that includes an awk print. I have 7
fields, I'd like to NOT print fields 3 and 7.

For something this simple I realize I could simply print 1,2,4,5, and
6 but there will be times later when the field count could be as high
as 14 and some of the lines may not have exactly 14 fields, but I will
never want fields 3 and 7.

In laymens terms I'd like it to do this:

blah | blah | blah | awk `!{print $3,$7}` | blah

Thanks.

~F
  Réponse avec citation
Vieux 23/07/2007, 06h30   #2
Ed Morton
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: awk !print$x

Faeandar wrote:
> I've got a multi pipe command that includes an awk print. I have 7
> fields, I'd like to NOT print fields 3 and 7.
>
> For something this simple I realize I could simply print 1,2,4,5, and
> 6 but there will be times later when the field count could be as high
> as 14 and some of the lines may not have exactly 14 fields, but I will
> never want fields 3 and 7.
>
> In laymens terms I'd like it to do this:
>
> blah | blah | blah | awk `!{print $3,$7}` | blah


If you don't care about the effect on white space between fields, then
all you need to do is empty the fields you don't care about:

blah | awk '{$3=$7=""}1' | blah

Otherwise, if your awk supports RE intervals, here's how to delete all
fields up to field N, preserving input formatting (gawk example):

gawk --re-interval 'sub(/^[[:space:]]*([^[:space:]]*[[:space:]]*){1}/,"")'
gawk --posix '...'

The number within the "{...}" is the number of initial fields to delete.
Note that "gensub()" is not available with "--posix" but it is available
with "--re-interval" so if you need to use an interval expression (e.g.
{1,} or {8} or {2,4}) with gensub() then you must use --re-interval
rather than --posix so --re-interval is generally the preferred method.

Mofdify the above to suit. If you're going to do that, though, you might
as well use the equivalent sed command.

Regards,

Ed.
  Réponse avec citation
Vieux 23/07/2007, 08h47   #3
Faeandar
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: awk !print$x

On Mon, 23 Jul 2007 00:30:18 -0500, Ed Morton <morton@lsupcaemnt.com>
wrote:

>Faeandar wrote:
>> I've got a multi pipe command that includes an awk print. I have 7
>> fields, I'd like to NOT print fields 3 and 7.
>>
>> For something this simple I realize I could simply print 1,2,4,5, and
>> 6 but there will be times later when the field count could be as high
>> as 14 and some of the lines may not have exactly 14 fields, but I will
>> never want fields 3 and 7.
>>
>> In laymens terms I'd like it to do this:
>>
>> blah | blah | blah | awk `!{print $3,$7}` | blah

>
>If you don't care about the effect on white space between fields, then
>all you need to do is empty the fields you don't care about:
>
>blah | awk '{$3=$7=""}1' | blah
>
>Otherwise, if your awk supports RE intervals, here's how to delete all
>fields up to field N, preserving input formatting (gawk example):
>
>gawk --re-interval 'sub(/^[[:space:]]*([^[:space:]]*[[:space:]]*){1}/,"")'
>gawk --posix '...'
>
>The number within the "{...}" is the number of initial fields to delete.
>Note that "gensub()" is not available with "--posix" but it is available
>with "--re-interval" so if you need to use an interval expression (e.g.
>{1,} or {8} or {2,4}) with gensub() then you must use --re-interval
>rather than --posix so --re-interval is generally the preferred method.
>
>Mofdify the above to suit. If you're going to do that, though, you might
>as well use the equivalent sed command.
>
>Regards,
>
> Ed.


What you just explained is going to take some research on my part just
to understand it, but you've given me a direction to at least look.
Thank you.

Out of curiosity, what is the equivalent sed command and why might I
as well use it instead of awk?

Thanks.

~F
  Réponse avec citation
Vieux 23/07/2007, 10h32   #4
loki harfagr
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: awk !print$x

On Mon, 23 Jul 2007 00:47:13 -0700, Faeandar wrote:

> On Mon, 23 Jul 2007 00:30:18 -0500, Ed Morton <morton@lsupcaemnt.com>
> wrote:
>
>>Faeandar wrote:
>>> I've got a multi pipe command that includes an awk print. I have 7
>>> fields, I'd like to NOT print fields 3 and 7.
>>>
>>> For something this simple I realize I could simply print 1,2,4,5, and
>>> 6 but there will be times later when the field count could be as high
>>> as 14 and some of the lines may not have exactly 14 fields, but I will
>>> never want fields 3 and 7.
>>>
>>> In laymens terms I'd like it to do this:
>>>
>>> blah | blah | blah | awk `!{print $3,$7}` | blah

>>
>>If you don't care about the effect on white space between fields, then
>>all you need to do is empty the fields you don't care about:
>>
>>blah | awk '{$3=$7=""}1' | blah
>>
>>Otherwise, if your awk supports RE intervals, here's how to delete all
>>fields up to field N, preserving input formatting (gawk example):
>>
>>gawk --re-interval
>>'sub(/^[[:space:]]*([^[:space:]]*[[:space:]]*){1}/,"")' gawk --posix
>>'...'
>>
>>The number within the "{...}" is the number of initial fields to delete.
>>Note that "gensub()" is not available with "--posix" but it is available
>>with "--re-interval" so if you need to use an interval expression (e.g.
>>{1,} or {8} or {2,4}) with gensub() then you must use --re-interval
>>rather than --posix so --re-interval is generally the preferred method.
>>
>>Mofdify the above to suit. If you're going to do that, though, you might
>>as well use the equivalent sed command.
>>
>>Regards,
>>
>> Ed.

>
> What you just explained is going to take some research on my part just
> to understand it, but you've given me a direction to at least look.
> Thank you.
>
> Out of curiosity, what is the equivalent sed command and why might I as
> well use it instead of awk?
>


I suppose this (one line) is approx. along the line of Ed. advice:

$ echo "one two three four five six seven and seven is" | sed 's/\([^[:space:]]*\) \([^[:space:]]*\) \([^[:space:]]*\) \([^[:space:]]*\) \([^[:space:]]*\) /\1 \2 \4 /'
one two four six seven and seven is


There are possibilities to make it more condensed but I think
for this kind of case that's clearer to start with a visually
direct expression :-)

I'd say you might as well use it instead of 'awk' because it'll
work as is in 'sed', without needing a special trigger or a specific awk
and using a rare function in it, on the other side 'sed' was almost
build for this use :-)
  Réponse avec citation
Vieux 23/07/2007, 12h44   #5
Kenny McCormack
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: awk !print$x

In article <YfednaeGI6JyoTnbnZ2dnUVZ_uGknZ2d@comcast.com>,
Ed Morton <morton@lsupcaemnt.com> wrote:
....
>If you don't care about the effect on white space between fields, then
>all you need to do is empty the fields you don't care about:
>
>blah | awk '{$3=$7=""}1' | blah
>
>Otherwise, if your awk supports RE intervals, here's how to delete all
>fields up to field N, preserving input formatting (gawk example):
>
>gawk --re-interval 'sub(/^[[:space:]]*([^[:space:]]*[[:space:]]*){1}/,"")'
>gawk --posix '...'


Isn't it simpler (conceptually, but not in the 'golf' sense) to just do
a loop? Gives you more control over the output. Something like (and,
yes, there are several variations on this, depending on your mood and/or
the phase of the moon - use this only as an example):

for (i=1; i<=NF; i++)
if (i != 3 && i != 7)
printf("%s%s",$i,i < NF ? " " : "\n")

(Yes, there could be an issue if NF == 7; left as exercise for the reader)

  Réponse avec citation
Vieux 23/07/2007, 13h02   #6
Ed Morton
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: awk !print$x

Kenny McCormack wrote:
> In article <YfednaeGI6JyoTnbnZ2dnUVZ_uGknZ2d@comcast.com>,
> Ed Morton <morton@lsupcaemnt.com> wrote:
> ...
>
>>If you don't care about the effect on white space between fields, then
>>all you need to do is empty the fields you don't care about:
>>
>>blah | awk '{$3=$7=""}1' | blah
>>
>>Otherwise, if your awk supports RE intervals, here's how to delete all
>>fields up to field N, preserving input formatting (gawk example):
>>
>>gawk --re-interval 'sub(/^[[:space:]]*([^[:space:]]*[[:space:]]*){1}/,"")'
>>gawk --posix '...'

>
>
> Isn't it simpler (conceptually, but not in the 'golf' sense) to just do
> a loop? Gives you more control over the output. Something like (and,
> yes, there are several variations on this, depending on your mood and/or
> the phase of the moon - use this only as an example):
>
> for (i=1; i<=NF; i++)
> if (i != 3 && i != 7)
> printf("%s%s",$i,i < NF ? " " : "\n")
>
> (Yes, there could be an issue if NF == 7; left as exercise for the reader)
>


That'd also change the white space between fields, so you may as well
just do $3=$7="".

Ed.
  Réponse avec citation
Vieux 23/07/2007, 13h05   #7
Robert Bonomi
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: awk !print$x

In article <dia8a3ldfm3n7j6v2fl3f0q72qep3u23q3@4ax.com>,
Faeandar <mr_castalot@yahoo.com> wrote:
>I've got a multi pipe command that includes an awk print. I have 7
>fields, I'd like to NOT print fields 3 and 7.
>
>For something this simple I realize I could simply print 1,2,4,5, and
>6 but there will be times later when the field count could be as high
>as 14 and some of the lines may not have exactly 14 fields, but I will
>never want fields 3 and 7.
>
>In laymens terms I'd like it to do this:
>
>blah | blah | blah | awk `!{print $3,$7}` | blah
>
>Thanks.
>
>~F


A number of things come to mind. none are particularly 'elegant', but all
will 'get the job done'.

1) if you refer to a field that does not exist, it (and any others
past the original 'last field' in the record) will be created and
set to a null value. Thus you could simply itemize out to field
14, and you'll just get extra trailing white-space when the input
record is less than 14 fields.

2) you can print individual fields with separate "printf" statements,
without causing them to be separate output 'records'.
by making the execution of the printf conditional on NF being at least
as big as the field it would be printing, you can get 'exactly' the
fields you want, with no trailing gubbage. of course you have to
unconditionally 'printf' a record-separator at the end of the 'conditional
printf' list.

3) variation on the above, copy first field into 'output' variable.
for fields 2, 4, 5, 6 append the output separator to the 'output'
variable, and then the indicate field. then for fields 8 to NF,
do the same thing. Then print the output variable.

4) you could save 'NF', do an 'offset copy' of the fields of interest
(e.g. copy field 4 into field 3, field 5 into field 4, 6 into 5,
8 into 6, 9 into 7, etc, through 14 into 12, decrement the 'saved'
NF value by 2, shove it back into NF, and print the record.

5) the _dirty_ way is to do the deed in two parts:
(a) simply set fields 3 and 7 to a _fixed_ 'unique' identifier that
you can guarantee will never appear in the data
(b) 'post-process' the awk output to remove the sequence that is
"{field_separator}{unique_value}"
the whole thing can be conceptually as simple as:
awk -e '{ $3="\b";$7="\b"rint; }' | sed -e '1,$s/ \b//g'
(note; untested! quoting and escaping may need to be tweaked)

6) an alternative to 5), above, is to null the fields and then 'gsub()'
the entire record to suppress the spurious fields before printing,
instead of using the additional sed process.


  Réponse avec citation
Vieux 23/07/2007, 15h04   #8
Icarus Sparry
Aucun Avatar
 
Messages: n/a
Hébergeur:
Par défaut Re: awk !print$x

On Mon, 23 Jul 2007 04:15:16 +0000, Faeandar wrote:

> I've got a multi pipe command that includes an awk print. I have 7
> fields, I'd like to NOT print fields 3 and 7.
>
> For something this simple I realize I could simply print 1,2,4,5, and 6
> but there will be times later when the field count could be as high as
> 14 and some of the lines may not have exactly 14 fields, but I will
> never want fields 3 and 7.
>
> In laymens terms I'd like it to do this:
>
> blah | blah | blah | awk `!{print $3,$7}` | blah
>
> Thanks.
>
> ~F


If you are not worried about spacing, just set the fields to the empty
string.

awk '{$3=""; $7="" ; print}'

It may be that "cut" is a better choice for this kind of problem.

cut -f1-2,4-6,8-
  Réponse avec citation
Réponse


Outils de la discussion

Règles de messages
Vous ne pouvez pas créer de nouvelles discussions
Vous ne pouvez pas envoyer des réponses
Vous ne pouvez pas envoyer des pièces jointes
Vous ne pouvez pas modifier vos messages

Les balises BB sont activées : oui
Les smileys sont activés : oui
La balise [IMG] est activée : oui
Le code HTML peut être employé : non
Trackbacks are oui
Pingbacks are oui
Refbacks are oui


Fuseau horaire GMT +1. Il est actuellement 09h35.


Édité par : vBulletin® version 3.7.3
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0 RC5 Tous droits réservés.
Version française #16 par l'association vBulletin francophone
PHWinfo est un site Éducation Sans Frontières ©2000-2008
Ad Management by RedTyger
©Tous droits réservés par les parties respectives
Page generated in 0,19715 seconds with 16 queries