47

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....

muru
  • 207,228
John
  • 579

12 Answers12

52

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'
ish
  • 141,990
11

SIMPLE METHOD

Another method using awk,

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

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!

M S
  • 271
4

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

Parto
  • 15,647
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.

Enlico
  • 272
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/

Parto
  • 15,647
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  
1

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

thomasrutter
  • 37,804
1
vim <your_file>

Type within vim and press Enter:

:% s/\n/ /g
muru
  • 207,228
Anatoly
  • 11
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
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.

0

Pure bash solution:

while read i; do printf '%s ' "$i"; done < file.txt > outfile.txt
evilsoup
  • 4,625