Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

awk -- get last field 1

Status
Not open for further replies.

gaspence

Technical User
Jan 5, 2005
4
US
Is there a way I can use 'awk' to return the last field of a query. For instance, lets say I have a file named 'abc def.txt' (Note: there is a white space between 'abc' and 'def.txt'). When I run the following command it does not return the complete file name for files with spaces in their name...

Code:
ls -lTp | awk '{print $6, $7, $9, $10}'

So the result for filename 'abc def.txt' would be...

Code:
12 Jan 2005 abc

Whereas a file named '123.txt' lists as...

Code:
12 Jan 2005 123.txt

Thanks all.

gaspence
 
Code:
ls -lTp | awk '{print $6, $7, $9, substr($0,X)}'
where X is the column in which the filename starts.
 
ls -lTp | awk '{s=$0;sub(".*"$10,$10,s);print $6, $7, $9, s}'

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
PHV, your solution fails when the filename is [tt]"foo foo"[/tt].
 
Good point futurelet.
ls -lTp | awk '{s=$0;sub(".*"$9" *"$10,$10,s);print $6, $7, $9, s}'

Hope This Helps, PH.
Want to get great answers to your Tek-Tips questions? Have a look at FAQ219-2884 or FAQ222-2244
 
PHV, your new solution fails with this line:
[tt]
-rw-r--r-- 3 oilc aaaaa 945 12 Jan xxx 2005 foo 2005 foo
[/tt]

This looks like an opportunity for me to use the function "shatter".
Code:
BEGIN { ORS="" }
{ shatter($0,f,"[ \t]+")
  print $6, $7, $9 " "
  for (i=19;i in f;i++)
    print f[i]
  print "\n"
}
# Unlike split(), builds array that contains the
# matching as well as the nonmatching substrings.
function shatter( s, array, re,    M )
{ delete array;   M = sprintf( "%c", 1 )
  if ( gsub( re, M "&" M, s  ) )
    return split( s, array, M )
  array[1] = s;   return 1
}
 
FYI AWK Compatibility:
you only 'delete array' in one swoop with either 'gawk' or POSIX awk [/usr/xpg4/bin/awk] (at least on Solaris).

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
vlad said:
you only 'delete array' in one swoop with either 'gawk' or POSIX awk [/usr/xpg4/bin/awk] (at least on Solaris).
Solaris seems quite brain-damaged.

[tt]delete array[/tt] works in mawk.

What is most important, it works in Brian Kernighan's "One True Awk". However, that use of "delete" is really not essential, is it? Wouldn't this do the same thing?
Code:
split( "", array )
 
good point, futurelet!

vlad
+----------------------------+
| #include<disclaimer.h> |
+----------------------------+
 
Vlad, taking into account your point that not all awks have a proper "delete", and since you agree that "split" can do the job, I'm changing the function. (And I realized that the "delete array" isn't needed if the "gsub" succeeds.)
Code:
# Unlike split(), builds array that contains the
# matching as well as the nonmatching substrings.
function shatter( s, array, re,    M )
{ M = sprintf( "%c", 1 )
  if ( gsub( re, M "&" M, s  ) )
    return split( s, array, M )
  split( "", array);   array[1] = s
  return 1
}
I think "shatter" is a rather nifty tool. I'm going to seize every chance to use it!
 
Thanks everybody, fantastic. PHV's solution worked best for my case.
 
I know it's not awk, but...

ls -l | tr -s ' ' | cut -d ' ' -f6,7,9-

 
Just empty the unwanted fields then print:
Code:
ls -lTp | awk '{$1="";$2="";$3="";$4="";$5="";$8=""; print}'

--------------------

Denis
 
Thanks for the tips on emptying the fields and using 'ls' to return a result. But as "futurelet" mentioned, double(+) spaced filenames are still coming out as a single spaced name...

Code:
foo     bar ## has 5 spaces
prints as...
foo bar ## has one space
 
double(+) spaced filenames are still coming out as a single spaced name...
Yes. That is precisely why I rejected the method of emptying the fields. When an assignment is made to a field, $0 is rebuilt by joining the fields with OFS between.
 
This seeemingly simple problem turned out to be rather thorny.

My previous solution was correct, but perhaps too verbose. In this one, we first build a regular expression that matches everything up to the filename.
Code:
BEGIN { OFS="[^ \\t]+[ \\t]+"
  $0 = "";   $10 = ""
  regexp = $0;   OFS = FS
}

{ match( $0, regexp )
  fname = substr( $0, RSTART + RLENGTH )
  print $6, $7, $9, fname
}
 
Thanks 'futurelet', and everyone else for the great answers and suggestions. I have learned a few new handy tricks just from this brief thread. You folks are another one of the reasons I love Unix ;- }

I'll be clicking the google ads in hope of supporting this fine site.

gaspence
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top