Reputation: 4364
I have input.txt
1
2
3
4
5
I need to get such output.txt
1,2,3,4,5
How to do it?
Upvotes: 83
Views: 126664
Reputation: 2766
This version does it all in bash, no external tools. It might not be portable to non-bash shells. (It works on bash and ksh, but not on dash)
# Load data into variable
indata=$(<input.txt)
# output data with shell parameter expansion
echo "${indata//$'\n'/,}" > output.txt
See the bash manual on the parameter expansion and Command substitution
Upvotes: 0
Reputation: 3027
Use paste
command. Here is using pipes:
echo "1\n2\n3\n4\n5" | paste -s -d, /dev/stdin
Here is using a file:
echo "1\n2\n3\n4\n5" > /tmp/input.txt
paste -s -d, /tmp/input.txt
Per man pages the s
concatenates all lines and d
allows to define the delimiter character.
Upvotes: 16
Reputation: 36058
printf "1\n2\n3" | tr '\n' ','
if you want to output that to a file just do
printf "1\n2\n3" | tr '\n' ',' > myFile
if you have the content in a file do
cat myInput.txt | tr '\n' ',' > myOutput.txt
Upvotes: 7
Reputation: 1704
python version:
python -c 'import sys; print(",".join(sys.stdin.read().splitlines()))'
Doesn't have the trailing comma problem (because join
works that way), and splitlines
splits data on native line endings (and removes them).
Upvotes: 2
Reputation: 345
tr
and sed
used be very good but when it comes to file parsing and regex you can't beat perl
(Not sure why people think that sed and tr are closer to shell than perl... )
perl -pe 's/\n/$1,/' your_file
if you want pure shell to do it then look at string matching
${string/#substring/replacement}
Upvotes: 13
Reputation: 7703
awk '{printf("%s,",$0)}' input.txt
awk 'BEGIN{ORS=","} {print $0}' input.txt
1,2,3,4,5,
Since you asked for 1,2,3,4,5
, as compared to 1,2,3,4,5,
(note the comma after 5, most of the solutions above also include the trailing comma), here are two more versions with Awk (with wc
and sed
) to get rid of the last comma:
i='input.txt'; awk -v c=$(wc -l $i | cut -d' ' -f1) '{printf("%s",$0);if(NR<c){printf(",")}}' $i
awk '{printf("%s,",$0)}' input.txt | sed 's/,\s*$//'
Upvotes: 12
Reputation: 246847
In response to @Jonathan's comment to @eumiro's answer:
tr -s '\r\n' ',' < input.txt | sed -e 's/,$/\n/' > output.txt
Upvotes: 22
Reputation: 754020
With sed
, you could use:
sed -e 'H;${x;s/\n/,/g;s/^,//;p;};d'
The H
appends the pattern space to the hold space (saving the current line in the hold space). The ${...}
surrounds actions that apply to the last line only. Those actions are: x
swap hold and pattern space; s/\n/,/g
substitute embedded newlines with commas; s/^,//
delete the leading comma (there's a newline at the start of the hold space); and p
print. The d
deletes the pattern space - no printing.
You could also use, therefore:
sed -n -e 'H;${x;s/\n/,/g;s/^,//;p;}'
The -n
suppresses default printing so the final d
is no longer needed.
This solution assumes that the CRLF line endings are the local native line ending (so you are working on DOS) and that sed
will therefore generate the local native line ending in the print operation. If you have DOS-format input but want Unix-format (LF only) output, then you have to work a bit harder - but you also need to stipulate this explicitly in the question.
It worked OK for me on MacOS X 10.6.5 with the numbers 1..5, and 1..50, and 1..5000 (23,893 characters in the single line of output); I'm not sure that I'd want to push it any harder than that.
Upvotes: 25