How can I join multiple lines into one line, with a separator where the new-line characters were, and avoiding a trailing separator and, optionally, ignoring empty lines?
Example. Consider a text file, foo.txt
, with three lines:
foo
bar
baz
The desired output is:
foo,bar,baz
The command I'm using now:
tr '\n' ',' <foo.txt |sed 's/,$//g'
Ideally it would be something like this:
cat foo.txt |join ,
What's:
- the most portable, concise, readable way.
- the most concise way using non-standard unix tools.
Of course I could write something, or just use an alias. But I'm interested to know the options.
How about to use xargs?
for your case
Be careful about the limit length of input of xargs command. (This means very long input file cannot be handled by this.)
Perhaps a little surprisingly,
paste
is a good way to do this:This won't deal with the empty lines you mentioned. For that, pipe your text through
grep
, first:Perl:
or yet shorter and faster, surprisingly:
or, if you want:
My answer is:
printf
is enough. We don't need-F"\n"
to change field separator.I needed to accomplish something similar, printing a comma-separated list of fields from a file, and was happy with piping STDOUT to
xargs
andruby
, like so:Just for fun, here's an all-builtins solution
You can use
printf
instead ofecho
if the trailing newline is a problem.This works by setting
IFS
, the delimiters thatread
will split on, to just newline and not other whitespace, then tellingread
to not stop reading until it reaches anul
, instead of the newline it usually uses, and to add each item read into the array (-a
) data. Then, in a subshell so as not to clobber theIFS
of the interactive shell, we setIFS
to,
and expand the array with*
, which delimits each item in the array with the first character inIFS