How to delete a character at the end of a file.

I am having a file which has data like this:-
1,2,3,4,5,

But I need to remove the last comma from this file. So the data should be like
1,2,3,4,5

The command I tried was

temp=`cat ${FileName}.txt`

len=`awk '{print length($0)}' ${FileName}.txt`

len=`expr $len - 1`

temp=`expr substr $temp 1 $len`

The problem here i am facing is if the data inside the file is very huge (say 1,2,3,4......9999,10000,)then it is giving error because the command (len=`awk '{print length($0)}' ${FileName}.txt`) returns two values for the variable like

len=10239

8651

Due to this the subsequent command fails.

Any help in this regard please.

Thanks & Regards,

Rony

 sed 's/,$//' filename > newfilename

Thanks Jim for your quick reply.

But for the sed command also i am getting it correct if the data is less but when it becomes big (say 1,2,3....5000,) it fails to write to the new file. So the new file is created as an empty file.

So is this is a limitation of UNIX or can we have some other work around for the problem.

Please help.

Thanks & Regards,
Rony

Yes. sed, vi, and other UNIX utilities that work on lines in files have a file record length limit. It's usually 2048 bytes per line (or record).

Look into fold to break lines into smaller pieces. Maybe. If you really have 1....5000
then you'll have to use C

/* cchop.c */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* if line ends in a comma, remove that ending comma */
/* usage  cchop < oldfile > newfile  - ONLY uses stdin stdout*/

int main(void)
{
	char tmp[64000]={0x0};  /*WAAAAY oversize */
	size_t len=0;
	
	while(fgets(tmp,sizeof(tmp),stdin)!=NULL)
	{
		char *p=strchr(tmp,0);
		p--;
		while(*p=='\n' || *p==',') 
		{
			*p=0x0;
			p--;
		}
		fprintf(stdout,"%s\n",tmp);
	}
	return 0;
}

Compile that and try it.

Thanks Jim. But i need to do it with shell script itself.

By the way if i change the structure of my source file as
1,
2,
3,
4,
5,
then the above problem of limitaion of length to a single record won't be there right? In that case how do i get the output as
1,2,3,4,5 ( no comma at the end).

I tried like this
awk 'sub(/$/,""){printf $0;next}
END { sub(/$/,""){printf $0;}
}' filename > newfilename

But this is giving me some error. How do i proceed with this??

Thanks,
Rony

The above command works if I put it like this

awk 'sub(/$/,""){printf $0;next}' filename>newfilename

But then the output would be
1,2,3,4,5,
The last comma (after 5) should not be there in the output.

Any help please

Try this :

awk '{line=line $0} END {sub(/,$/, "", line) ;print line}'

Great aigles !!

Thank you very much. This is what I was looking for.

But frankly I didn't understand the code. Could please explain why we are puting line=line $0. Are you concatinating the previous value of line with the present value?

Again one more problem I face in this code is that if the number of records in the source file becomes more than 5000, then I am getting the error
Segmentation fault(coredump)
in AIX.

Thanks,
Rony

awk 'substr($0,length($0)) == "," {print substr($0,1,length($0)-1) substr($0,length($0)) != "," {print $0}' <filename>

This code have a missing "}". I guess it should be like this
awk 'substr($0,length($0)) == "," {print substr($0,1,length($0)-1)} substr($0,length($0)) != "," {print $0}' filename
Correct me if I am wrong.

The ouput i get here is like this
1
2
3
4
5
But this is not what I want. I have to the get the output as
1,2,3,4,5

Another solution without concatenation :

awk '
NR==1 {         # Memorize first record whitout printing it
   line = $0;
   next;
}
{                  
   printf("%s",line); # Print previous record without ending Line Feed
   line=$0              # Memorize current record
} 
END {
   sub(/,$/,"",line);  # Remove trailing "," on last record
   print line            # Print last record
}
' input_file > output file

Another solution wiyhout awk :

sed '$s/,$//' < input_file | tr -d '\n'> output_file

In that case, the output file is not ending with a line feed.
You can add it :

echo >> output_file

awk 'NR > 1 {print l} {l=$0} END {sub(/,$/,"",l);print l}' <filename>

Great aigles !!
Both the code suggested by you is working fine and is excatly what I wanted. I tried this with a huge input file and still it's able to handle it without any errors.

Thank you very much aigles .

Thanks rajeeb_d for your help.
Your code is also giving the ouput for a large input file but the problem is that it is not putting the output in a single line. The output is coming as
1,
2,
3,
4,
5
Whereas my requirement is to get the output as
1,2,3,4,5

Once again thanks to all who have taken time and effort to help me out.

Regards,
Rony