LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   How to remove the last \n from a file . (https://www.linuxquestions.org/questions/linux-newbie-8/how-to-remove-the-last-%5Cn-from-a-file-794369/)

sumanch 03-10-2010 12:41 AM

How to remove the last \n from a file .
 
I have a file sample.xml . If I do "vi sample.xml" I can see the following

bash$ cat sample.xml
<content/>
bash$

but I don't want the last \n character so that it becomes following

bash$ cat sample.xml
<content/>bash$

Please let me know how do I achieve that ?

regards
Suman

vinaytp 03-10-2010 01:02 AM

Very simple
Code:

tr -d '\n'< sample.xml

kainosnous 03-10-2010 03:01 AM

Personally, I would just edit it in vi. Just type G and dd and you should be done. Was this a one time thing, or did you need a script to do this?

catkin 03-10-2010 03:05 AM

Quote:

Originally Posted by vinaytp (Post 3892497)
Very simple
Code:

tr -d '\n'< sample.xml

That would delete all line endings from sample.xml. Even if it were modified to remove only the/any line end from the end of the file it would not print the bash prompt after the file contents as the OP wants because bash starts a new line after command output, before displaying the prompt, as in this example:
Code:

c@CW8:~$ < /dev/null
c@CW8:~$

The only time I recall seeing the bash prompt immediately after command output is when the terminal's line end handling has been disabled, usually by accidentally sending the contents of a binary file to the terminal.

kainosnous 03-10-2010 03:21 AM

catkin is right. I missed that. It will still start the prompt on a new line. What were you trying to do? Perhaps there is another approach.

vinaytp 03-10-2010 04:21 AM

Quote:

Originally Posted by kainosnous (Post 3892589)
Personally, I would just edit it in vi. Just type G and dd and you should be done. Was this a one time thing, or did you need a script to do this?

Could you pleas tell me how this works ? Hope this deletes entire last line. Also even after deleting last line you will end up with \n in last but one line.

you may inspect this with Ocatal dump after G and dd
Code:

od -t c sample.xml
I thought \n has to be deleted entirely from the file. If you want to delete it only form the last line why can't you write a simple script to do that. Something similar to below will do

Code:

var=`wc sample.xml | tr -s ' ' | cut -d ' ' -f 2`
lines=`expr $var - 1`
head -n $lines sample.xml ; tail -1 sample.xml | tr -d '\n'


colucix 03-10-2010 04:58 AM

I have some doubts about bash printing a new prompt on a new line after command output. If you print out some text that misses the last newline, the prompt should actually be placed inline. For example, here is an alternative in gawk to remove the last newline (I think sed can do it better, but I cannot catch it, now...):
Code:

[colucix@ocean-4 ~]$ cat testfile
line one
line two
line three
[colucix@ocean-4 ~]$ awk 'NR==1{("cat " FILENAME " | wc -l") | getline NL} NR < NL; END{printf "%s", $0}' testfile
line one
line two
line three[colucix@ocean-4 ~]$

Furthermore, if I redirect the output to a file and print out the content using cat:
Code:

[colucix@ocean-4 ~]$ awk 'NR==1{("cat " FILENAME " | wc -l") | getline NL} NR < NL; END{printf "%s", $0}' testfile > testfile_modified
[colucix@ocean-4 ~]$ cat testfile_modified
line one
line two
line three[colucix@ocean-4 ~]$

In other words apparently bash puts the prompt on a new line when you type a command (that does not produce any output) and press enter: actually, it puts the prompt on the same line with... "nothing".

Kenhelm 03-10-2010 12:06 PM

Code:

# Remove the last byte in a file
head -c-1 sample.xml > newsample.xml

# Remove the last byte in a file only if it is a newline.
# If the last byte isn't a '\n' then grep adds one, head removes it.
grep '^' sample.xml | head -c-1 - > newsample.xml


colucix 03-10-2010 12:25 PM

Quote:

Originally Posted by Kenhelm (Post 3893146)
Code:

# Remove the last byte in a file
head -c-1 sample.xml > newsample.xml

# Remove the last byte in a file only if it is a newline.
# If the last byte isn't a '\n' then grep adds one, head removes it.
grep '^' sample.xml | head -c-1 - > newsample.xml


Nice. Good catch!

jamescondron 03-10-2010 12:32 PM

You're all missing the point; the last line break is supposed to be there, its pretty important that it is, though for the life of me I can't remember why; something to do with how the FS works.

Bugger, let me find a link


EDIT:
Thats why, you need it for opening files in append mode, for code (some compilers crap themselves without it), for importing text as input.

The line isn't a '\n' at all. Open it in a hex editor and see

sundialsvcs 03-10-2010 10:59 PM

chomp! :hattip:

vinaytp 03-10-2010 11:04 PM

Quote:

Originally Posted by Kenhelm (Post 3893146)
Code:

# Remove the last byte in a file
head -c-1 sample.xml > newsample.xml

# Remove the last byte in a file only if it is a newline.
# If the last byte isn't a '\n' then grep adds one, head removes it.
grep '^' sample.xml | head -c-1 - > newsample.xml


Yeah, that's better.
Good sense of switch usage.

ghostdog74 03-10-2010 11:27 PM

Code:

awk '{q=p;p=$0}NR>1{print q}END{ORS = ""; print p}' file

aggresss 01-01-2019 09:09 AM

Helpful idea
 
It works , thanks a lot !

Quote:

Originally Posted by colucix (Post 3892680)
I have some doubts about bash printing a new prompt on a new line after command output. If you print out some text that misses the last newline, the prompt should actually be placed inline. For example, here is an alternative in gawk to remove the last newline (I think sed can do it better, but I cannot catch it, now...):
Code:

[colucix@ocean-4 ~]$ cat testfile
line one
line two
line three
[colucix@ocean-4 ~]$ awk 'NR==1{("cat " FILENAME " | wc -l") | getline NL} NR < NL; END{printf "%s", $0}' testfile
line one
line two
line three[colucix@ocean-4 ~]$

Furthermore, if I redirect the output to a file and print out the content using cat:
Code:

[colucix@ocean-4 ~]$ awk 'NR==1{("cat " FILENAME " | wc -l") | getline NL} NR < NL; END{printf "%s", $0}' testfile > testfile_modified
[colucix@ocean-4 ~]$ cat testfile_modified
line one
line two
line three[colucix@ocean-4 ~]$

In other words apparently bash puts the prompt on a new line when you type a command (that does not produce any output) and press enter: actually, it puts the prompt on the same line with... "nothing".


MadeInGermany 01-01-2019 12:52 PM

With shell builtins
Code:

nl=
while IFS= read line
do
  printf "$nl%s" "$line"
  nl='\n'
done < textfile > incompletefile

Note that the standard text processing tools (like sed and awk) might not properly handle an incomplete text file.
So more often you want to do the opposite
Code:

{
while IFS= read line
do
  echo "$line"
done
[ -n "$line" ] && echo "$line"
} < incompletefile > textfile



All times are GMT -5. The time now is 12:05 AM.