How to print the without last column?

hi Gurus,

I want print out the file without last column. I am not able to figure out the command , any body can help me this?

thanks in advancd.

Hello Ken6503,

You can do the following. Not tested though, you can try and let us know if this helps.

awk  '{$NF="\b"} 1'  Input_file
OR
awk '(NF=NF-1) 1' Input_file

Thanks,
R. Singh

1 Like

Try

awk 'NF-=1' file
1 Like

This heavily depends on the OS and command versions, which you fail to mention.

awk 'NF{NF-=1}1' file

works on my linux machine;

awk '{$NF=""}1' file

on FreeBSD as well.

@Akshay Hegde: Did you try that on an empty line? (same for RavinderSingh13's second proposal).

1 Like

Thanks R.Singh,

the first command works for me. but I have some issue with it. my data as below:

003875549712|1003875549712|30832
1003897950712|1003897950712|30832
1004928111712|1004928111712|85841
1004928283712|1004928283712|85841
1004928556712|1004928556712|85841

after run command:

nawk -F'|' '{$NF="\b"}1' OFS='|' test
003875549712|1003875549712|
1003897950712|1003897950712|
1004928111712|1004928111712|
1004928283712|1004928283712|
1004928556712|1004928556712|

there is extra '|' at end of each line.
how could I fix this?
by the way.
would you please briefly explain what's the "\b" mean?

command

nawk -F'|' '(NF=NF-1) 1' test

doesn't work for me.
I run it and got same result as input.

003875549712|1003875549712|30832
1003897950712|1003897950712|30832
1004928111712|1004928111712|85841
1004928283712|1004928283712|85841
1004928556712|1004928556712|85841

My OS is Solaris.

Thanks in advance.

---------- Post updated at 03:34 PM ---------- Previous update was at 03:29 PM ----------

Thanks Akshay Hegde,
when running this command, I got same result as input file.

$cat test
003875549712|1003875549712|30832
1003897950712|1003897950712|30832
1004928111712|1004928111712|85841
1004928283712|1004928283712|85841
1004928556712|1004928556712|85841
$nawk -F'|' 'NF-=1' test
003875549712|1003875549712|30832
1003897950712|1003897950712|30832
1004928111712|1004928111712|85841
1004928283712|1004928283712|85841
1004928556712|1004928556712|85841

is this because of OS?

My OS is Solaris.

thanks in advance.

---------- Post updated at 03:41 PM ---------- Previous update was at 03:34 PM ----------

Thanks RudiC.

command

awk 'NF{NF-=1}1' file

gave me same data as input file.
command

awk '{$NF=""}1' file

works, but there is a extra '|' at each end of line.

what's "" mean in $NF=""?

Thanks in advance.

$cat test
003875549712|1003875549712|30832
1003897950712|1003897950712|30832
1004928111712|1004928111712|85841
1004928283712|1004928283712|85841
1004928556712|1004928556712|85841
$nawk -F'|' 'NF{NF-=1}1' test
003875549712|1003875549712|30832
1003897950712|1003897950712|30832
1004928111712|1004928111712|85841
1004928283712|1004928283712|85841
1004928556712|1004928556712|85841
$nawk -F'|' '{$NF=""}1' OFS='|' test
003875549712|1003875549712|
1003897950712|1003897950712|
1004928111712|1004928111712|
1004928283712|1004928283712|
1004928556712|1004928556712|

Hello Ken,

Following may help you.

awk -F"|" 'NF{NF=NF-1} 1' OFS="|" Input_file

Output will be as follows.

003875549712|1003875549712
1003897950712|1003897950712
1004928111712|1004928111712
1004928283712|1004928283712
1004928556712|1004928556712

Thanks,
R. Singh

1 Like

NF is a built-in variable that will contain the Number of Fields in the current read record. Therefore:
print NF will display the a number, representing the number of fields
print $NF will display the value of the last field.
$NF="" will set the last field value to empty, erasing the previous content of last field

1 Like
sed 's/|[^|]*$//' file

If all you want to do is to get rid of the last field and none of your input lines contain a single field, MadeInGermany's suggestion using sed is probably better than using awk . If you want to do this using any awk ( /usr/xpg4/bin/awk , /usr/xpg6/bin/awk , or nawk on Solaris/SunOS systems), try:

nawk '
BEGIN {	FS = OFS = "|" }
NF < 2 {print ""; next }
{	NF -= 1; $1 = $1; print }
' file
perl -wlnaF\| -e '@F = splice @F, 0, -1; $" = "|"; print "@F"' file
perl -wlnaF\| -e '$" = "|"; print "@F[0..$#F-1]";' file

Empty the last field then remove its delimiter

sed 's/[^|]*$//;s/|$//' file

The trouble with manipulation of NF is that its effect is not specified by POSIX, so if there is an effect, it is implementation-specific.
So I think in awk the regex route is the most reliable way, or removing the last field and field separator, so:

awk '{$NF=x; sub(/\|$/,x)}1' FS=\| OFS=\| file

(which is analogous to MadeinGermany's sed suggestion) or

awk '{sub(/\|?[^|]*$/,x)}1' file

With sed:

sed 's/|\{0,1\}[^|]*$//' file

GNU sed -r or BSD sed -E :

sed -r 's/\|?[^|]*$//' file

--

Hi Don, that works with nawk , but it does not appear to work with /usr/xpg4/bin/awk .
I have not come across /usr/xpg6/bin/awk is that part of Solaris 11 or is that available as part of an additional package?

1 Like

Hi Scrutinizer,
Thanks for the information. I no longer have access to a Solaris system to test these types of things. I didn't realize there was a difference in the way NF was handled in nawk and /usr/xpg[46]/awk . (One key difference between the three is which shell is used when you use the awk system() function ( /bin/sh , /usr/xpg4/bin/sh , or /usr/xpg6/bin/sh , respectively)). The Solaris nawk comes straight from the AT&T new awk from the 1980's. I don't remember where the base source for /usr/xpg[46]/bin/awk came from.

The /usr/xpg6 hierarchy should be available on any Solaris system released since about 2004 or 2005, but it may have been an install time option rather than part of the default install.

The code I suggested works on OS X, so it probably works on BSD derived versions of awk . (And, this isn't surprising since the new awk came out of AT&T's Research UNIX group rather than AT&T's Programmer's Workbench UNIX group.)

nawk -F"|"  'NR>0{NF-=1}$1=$1' OFS="|" file