concatenating non blank lines with sed
Hello,
I have a question so easy that I'm embarrassed to write it up as a post on this forum. I want sed to substitute the newline character with the tab character on any non-blank line. Feeling like that was WELL within my admittedly beginner level bash scripting abilities, I typed Quote:
As an addendum, I really do try to solve these for myself before coming to this forum; and it pains me to come to you guys with such a simple problem, but I can't figure it out. |
Hi.
How about awk: Code:
$ echo -e '1\n2\n3\n\n4' | awk '$1=$1' RS='\n\n' OFS='\t' |
Code:
sed -e :a -e 'N; s/\n/\t/; ta' <filename N is the patternspace, it holds the current line. BTW: a very interesting problem when done with sed Markus |
Quote:
Code:
sed ':a N; s/\n/\t/; ta' Code:
sed -n '$!{/^$/{x;s/\n/\t/g;s/^\t//;p;g;/./p;b};H;b};p' |
millgates, thanks for correcting me
Code:
sed ':a /^$/!N; s/\n/\t/; ta' Markus |
Quote:
"I want to substitute a tab character for the newline character on any non-blank line." If this interpretation is correct, all blank lines in an input file should be left unchanged. Let's remember that a "blank line" could consist of zero or more blank characters. I learn by reading forum posts and solving when I can. I also test proposed solutions offered by others. This is a test file constructed for the purpose: Code:
This is a non-blank line with no trailing blanks. Daniel B. Martin |
Quote:
Code:
$ echo -e "a\nb\nc\n\nd e\n\n\nf"|sed ':a /^$/!N;s/\n/\t/; ta' let's have a file like this: Code:
a 1) sed reads the first line: a 2) /^$/ will not match, so !N will append next line to the pattern space. 3) The contents of the pattern space is now "a\nb". 4) s/\n/\t/ will replace the \n with \t and ta will return the flow back to the begining of the expression. 5) /^$/ will not match again, next line (blank) is read and appended (with a newline) to the pattern space. 6) The pattern space now contains "a\tb\n" and the substitution will again succeed. 7) /^$/ will not match (it never will except if the first line is blank), the last line is read and appended to the pattern space, newline gets substituted 8) reaches the end of input and the entire pattern space is sent to stdout: a\tb\t\t\c\n |
Hi.
Here is a space-inefficient sed solution: Code:
$ echo -e '1aaa\n2bb\n3cc\n\n\n4dd\n\n5\n6' | sed -nr 'H; ${x; s/\n\n/&\n/g;s/([^\n])\n/\1\t/g; s/^\n//p}' |
Don't have much in the way of sedfu, but the following awk seems to work:
Code:
awk '!NF{printf "\n";if(x)next;x=1}NF{x=0}ORS=NF?"\t":"\n"' |
Quote:
Markus |
Also, since I don't have anything better to do, what about perl?
Code:
perl -pe 'chomp;$_.=$_?"\t":"\n";' Code:
perl -0777 -pe 's/(?<=[^\n])\n(?=[^\n])/\t/g;' |
Quote:
As per OP: Quote:
|
grail, I think you're right, now I tried perl
Code:
perl -pe 's/(.+[a-zA-Z].+)\n/$1\t/g;' When one writes a complete script, it is necessary to undef $/ Code:
#!/usr/bin/perl |
The sedfaq sections 4.25 and 4.26 has solutions for concatenating lines based on their contents:
http://sed.sourceforge.net/sedfaq4.html#s4.25 To concat all non-blank lines, just use a generic matching pattern, such as '.$'. |
Quote:
I had with sed and Perl as well some difficulties to match blank lines which contain whitespaces. I'm somewhat confused here. Markus |
All times are GMT -5. The time now is 05:35 PM. |