Classified
Classified

Reputation: 6060

How do I join the previous line with the current line with sed?

I have a file with the following content.

test1
test2
test3
test4
test5

If I want to concatenate all lines into one line separated by commas, I can use vi and run the following command:

:%s/\n/,/g

I then get this, which is what I want

test1,test2,test3,test4,test5,

I'm trying to use sed to do the same thing but I'm missing some unknown command/option to make it work. When I look at the file in vi and search for "\n" or "$", it finds the newline or end of line. However, when I tell sed to look for a newline, it pretends it didn't find one.

$ cat test | sed --expression='s/\n/,/g'
test1
test2
test3
test4
test5
$

If I tell sed to look for end of line, it finds it and inserts the comma but it doesn't concatenate everything into one line.

$ cat test | sed --expression='s/$/,/g'
test1,
test2,
test3,
test4,
test5,
$

What command/option do I use with sed to make it concatenate everything into one line and replace the end of line/newline with a comma?

Upvotes: 1

Views: 410

Answers (4)

potong
potong

Reputation: 58453

This might work for you (GNU sed):

sed 'H;1h;$!d;x;y/\n/,/' file

Append all lines but the first to the hold space (the first replaces the hold space).

If it is not the last line of the file, delete it.

Otherwise, swap to the hold space and translate all newlines to commas.

Upvotes: 0

azbarcea
azbarcea

Reputation: 3657

Based on how can i replace each newline n with a space using sed:

sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/,/g' <file>

testing:

$ cat file.txt
test1
test2
test3
test4
test5

$ sed -e ':a' -e 'N' -e '$!ba' -e 's/\n/,/g' file.txt
test1,test2,test3,test4,test5

Of course, if the question would have been more generic: How do I replace \n with any character using sed then one should only replace the , with ones desired char:

export CHAR_TO_REPLACE=','
export FILE_TO_PROCESS=<filename>
sed -e ':a' -e 'N' -e '$!ba' -e "s/\n/${CHAR_TO_REPLACE}/g" $FILE_TO_PROCESS

This answer is to satisfy the requirement of using sed. Otherwise, you can use alternatives like tr, awk etc.

Upvotes: -1

glenn jackman
glenn jackman

Reputation: 246942

reads one line at a time, so, unless you're doing tricky things, there's never a newline to replace.

Here's the trickiness:

$ sed -n '1{h; n}; H; ${g; s/\n/,/gp}' test.file
test1,test2,test3,test4,test5

h, H, g documented at https://www.gnu.org/software/sed/manual/html_node/Other-Commands.html

When using a non-GNU sed, as found on MacOS, semi-colons before the closing braces are needed.

However, is really the tool for this job

$ paste -s -d, test.file
test1,test2,test3,test4,test5

If you really want the trailing comma:

printf '%s,\n' "$(paste -sd, file)"

Upvotes: 4

Shawn
Shawn

Reputation: 52449

tr instead of sed for this one:

$ tr '\n' ',' < input.txt
test1,test2,test3,test4,test5,

Just straight up translate newlines to commas.

Upvotes: 4

Related Questions