41

I want to get all lines in a text into one line. I'm a beginner at coding trying to learn by doing. I've spent four hours trying to solve this problem. I know there's a simple solution to this problem. Here's what I've been trying.

sed -e 'N;s/\n//' myfile.txt #Does nothing

sed -e :a -e N -e 's/\n/ /' -e ta myfile.txt #output all messed up and I can't make head nor tail of the syntax

cat myfile.txt | tr -d '\n' > myfile.txt # Deletes all lines

Here's the text file:

500212
262578-4-4
23200
GRIFFITH LABORATORIES LTD
GRIFFITH LABORATORIES
SOUTH DUBLIN COUNTY COUNCIL
OFFICE
OFFICE (INDUSTRIAL)
List Rateable
2 Pineview Industrial Estate
Firhouse Road
Knocklyon
31 Dec 2007
01 Jan 2008"   

I can't figure out where I've gone wrong....

12 Answers 12

46

tr as you used it should work and is the simplest -- you just need to output to another file. If you use the input file as output, the result is an empty file as you observed;

cat myfile.txt | tr -d '\n' > oneline.txt

You need to remember some editors terminate a line with \r\n. For that case, use

cat myfile | tr -d '\r\n'
9
  • Thanks for your help but it's still not working. I know it's saomething basic and simple. The command you gave deleted all lines. I'm going to post the file 500212 262578-4-4 23200 GRIFFITH LABORATORIES LTD GRIFFITH LABORATORIES SOUTH DUBLIN COUNTY COUNCIL OFFICE OFFICE (INDUSTRIAL) List Rateable 2 Pineview Industrial Estate Firhouse Road Knocklyon 31 Dec 2007 01 Jan 2008
    – John
    Jul 16, 2012 at 11:30
  • @JOhn: What is the result or error?
    – ish
    Jul 16, 2012 at 11:31
  • I was going to post by editing my answer. After I used the command the file was blank. It looked like this in the terminal "cat reval_details.asp?Pno=500211.txt | tr -d '\n' > reval_details.asp?Pno=500211.txt". Thanks again.
    – John
    Jul 16, 2012 at 11:49
  • 4
    A better way of doing this would be tr -d '\n' <input.txt > output.txt - that avoids the useless use of cat, and uses one less unnecessary pipe.
    – evilsoup
    Jan 31, 2013 at 15:27
  • 1
    If the input file consists of words, I would not only remove the line-feeds, but to replace them with spaces in order to make the long string more readable: <input.txt tr '\n' ' ' > output.txt
    – sudodus
    Jun 2, 2021 at 19:42
9

SIMPLE METHOD

Another method using awk,

cat myfile.txt | awk '{print}' ORS=''

Output:

500212262578-4-423200GRIFFITH LABORATORIES LTDGRIFFITH LABORATORIESSOUTH DUBLIN COUNTY COUNCILOFFICEOFFICE (INDUSTRIAL)List Rateable2 Pineview Industrial EstateFirhouse RoadKnocklyon31 Dec 200701 Jan 2008"

Note:

ORS='' -> ORS(Output Record Separator). (i.e) your field separator, you can have any characters in-between the single quotes as a field separator. Using this awk method we can include spaces and all characters.

Hope this might help!

2
3

GEDIT:

Search and replace \n with a space ' '.
You can get the replace window by going to 'Search'->'Replace'
or via the keybpard shortcut Ctrl+H

See screenshot below:

Your original text is on lines 1-14.
The result is on line 16.

enter image description here

3

I think the easiest way to do this is:

paste -s -d:" " test.txt

http://ss64.com/bash/paste.html

3

There's no need to put the label :a outside of the main instruction, neither is the -e option necessary needed; finally, the /$/ is superfluous (every line has an EOL character).

Improving other answers, one gets

sed -i ':a; N; s/\n/ /; ta' file

Which is clearer if written as follows,

sed -i ':a
        N
        s/\n/ /
        ta' file

The command works as follows:

  1. N appends the next line to the (multiline) pattern space, which contains the current line already;
  2. s/\n/ / substitute the newline character \n generated by N with a space ;
  3. ta goes to the script line following the label :a as long as the substitution in step 2 was successful, i.e. if the substitution occurred, the execution jumps to step 1 without "hitting" the end of script, i.e. without reading another line of input.

Note the following;

  • sed reads the lines of the input file one by one in order, starting from the 1st line;
  • :a is just a label, not a command to be executed;
  • N is, in principle, executed on any line, but
  • s/\n/ / (in principle executed on any line) is successful on any line but the last one, so
  • ta makes the end of the script reachable only when the last line of input is read (the only line where s fails), so
  • no further input line is read into the pattern space after the 1st one is read into it, unless the last one is read in, but then there's no further line to read in, and the implicit p command is executed.

So the script basically reads in the 1st line of input and keeps appending the following lines one by one, each time substituting the newline with a space; after the last line is appended (and \n changed in a space), N can't append any line, s fails, ta is skipped, the end of the script is reached, and the implied print statement is executed on the current looong 1-line pattern space.

The -i option substitutes the input file file with the whole 1-line pattern space.

2

Try this

sed -e :a -e '/$/N; s/\n/\\n/; ta' [filename]

http://anandsekar.github.io/joining-all-lines-in-a-file-using-sed/

1
  • 2
    Could you give more details / explanation about all these switches ? It can make to understand better why it is working or not.
    – Benoit
    Aug 20, 2014 at 11:28
2

Python approach:

python -c "import sys; print(' '.join([ l.strip() for l in sys.stdin.readlines() ]))" < input.txt

AWK:

awk '{printf "%s ",$0}' /etc/passwd  
0

I think you were simply forgetting that you needed to tell sed to redirect the output of yourfile.txt to the desired result, newfile.txt. This appears to be the command you need, but only if the files you are trying to merge are not too big for sed's buffers: sed -e :a -e N -e 's/\n/ /' -e ta yourfile.txt >newfile.txt. Credit to another forum here, where they discuss sed's capabilities. I have tested the command and it worked for me.

5
  • 1
    Actually, sed with the -i switch will modify the original file inline, so there's no need to output to another file. Be careful though!
    – ish
    Jul 16, 2012 at 8:17
  • I tried sed -e :a -e N -e 's/\n/ /' -e ta reval_details.asp?Pno=500214.txt 01 Jan 2008addustrial Estate sed -i :a -e N -e 's/\n/ /' -e ta reval_details.asp?Pno=500214.txt sed: can't find label for jump to a' sed -i :a -e N -i 's/\n/ /' -e ta reval_details.asp?Pno=500214.txt sed: can't find label for jump to a' sed -e :a -e N -i 's/\n/ /' -e ta reval_details.asp?Pno=500214.txt sed: can't read s/\n/ /: No such file or directory #Any ideas.
    – John
    Jul 16, 2012 at 12:09
  • @Mik I've still had no luck but thanks for the reply.
    – John
    Jul 16, 2012 at 12:13
  • I copy and pasted your text into a text editor and saved the file then used my sed command and it made it all appear on one line when opened in nano; however if you open out the file using cat in the terminal it will be wrapped and not appear to be just one line, so perhaps that's what's happening. Also, you don't need a' before sed and I think you've added some other unnecessary elements to the command above, so try sed -e :a -e N -e 's/\n/ /' -e ta yourfile.txt >newfile.txt The line is so long it will appear wrapped on screen, however, unless you have a 30+ inch monitor!
    – user76204
    Jul 16, 2012 at 12:23
  • @Mik Cheers for the post. I typed my data into a text editor saved it and ran ' sed -e :a -e N -e 's/\n/ /' -e ta abc.txt >abc1.txt ' and it worked. perfectly. Hallelujah. I then typed ' sed -e :a -e N -e 's/\n/ /' -e ta reval_details.asp?Pno=500215.txt >Pno=500215.txt ' and every line apart from the first had a space added to the start of the line. I appreciate the effort you put in but I think I'll move on to octave and try and process the data there.
    – John
    Jul 16, 2012 at 13:03
0

Pure bash solution:

while read i; do printf '%s ' "$i"; done < file.txt > outfile.txt
0

If it were me I'd just open it in vim and press Shift+J a few times.

0
vim <your_file>

Type within vim and press Enter:

:% s/\n/ /g
0

With no subshell or external command calls makes it fairly fast, at least on smaller reads.

mapfile -t < file; echo "${MAPFILE[*]}" > file

It is possible to achieve the same with read.

read -rd '' -a a < file; echo "${a[*]}" > file

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .