问题
I'm trying to do something like this but for quoted emails, so this
On 2014-07-11 at 03:36 PM, <ilovespaces@email.com> wrote:
>Hi Everyone,
>
>
>
>I love spaces.
>
>
>
>That's all.
Would become this
On 2014-07-11 at 03:36 PM, <ilovespaces@email.com> wrote:
>Hi Everyone,
>
>I love spaces.
>
>That's all.
Thanks
回答1:
Assuming that each visual line is a proper logical line (string of characters ended with a \n
), you can dispense with the rest of the tools and simply run uniq(1)
on the input.
Example follows.
% cat tst
>Hi Everyone,
>
>
>
>I love spaces.
>
>
>
>That's all.
% uniq tst
>Hi Everyone,
>
>I love spaces.
>
>That's all.
%
回答2:
sed '/^>\s\s*$/d;$b;/^[^>]/b;a>' input
Means:
/^>\s\s*$/d
: Delete all lines with a single >
and whitespace.
$b;/^[^>]/b
: Print and skip the last line, an lines not starting with >
.
a>
: Add a >
after all other lines.
Gives:
On 2014-07-11 at 03:36 PM, <ilovespaces@email.com> wrote:
>Hi Everyone,
>
>I love spaces.
>
>That's all.
回答3:
Try this:
sed -r '/^>\s*$/{N;/^>\s*\n>\s*$/D}'
Here is the explanation:
Commands used:
N
Append the next line of input into the pattern space.D
Delete up to the first embedded newline in the pattern space. Start next cycle, but skip reading from the input if there is still data in the pattern space.
Patterns used:
/^>\s*$/
matches a line contains '>' with zero or more spaces followed/^>\s*\n>\s*$/
matches two continuous lines contains>
with zero or more spaces followed when using together withN
So the above sed
command's work flow is:
- read a line into pattern space(if meets the end of file, exit)
- if pattern space only contains '>' go to step 4 else go to step 3
- print the context in pattern space and go to step 1
- append '\n' and next line to pattern space, if the pattern space only contains '>\n>'(which means we meet two continuous '>' lines) go to step 5 else go to step 3
- delete the context before '\n'(included) and then go to step 2
回答4:
Another awk-based solution:
awk '{ /^>\s*$/?b++:b=0; if (b<=1) print }' file
Breakdown:
/^>\s*$/?b++:b=0
- ? : the ternary operator
- /^>\s*$/ matches a blank line starts with ">"
- b variable that counts consecutive blank lines (b++).
however, if the current line is non-blank, b is reset to 0.
if (b<=1) print
print if the current line is non-blank (b==0)
or if there is only one blank line (b==1).
回答5:
awk way
This actually takes into account the spaces unlike other answers(except perreals :))
It also doesnt just insert a >
after every line with more than >
on it (meaning that if there were multiple lines with text, blank lines would not be inserted between them.)
awk 'a=/^>[ ]*$/{x=$1}!a&&x{print x;x=0}!a' file
Explanation
a=/^>[ ]*$/ Sets a to pattern. Pattern is begins with > and
then has only spaces till end
{x=$1} Sets x to $1.
!a&&x While it does not match a(the pattern) and x is 0
{print x;x=0} Print x(>) and set x to zero
!a If it is not a(the pattern) print the line
The way this work is it sets x to > when it finds a line containing only > and spaces.
Then Carries on until it finds a line that doesn't match, prints > and prints the line.
This resets everytime it finds the pattern again
Hope this helps :)
来源:https://stackoverflow.com/questions/24771519/replying-to-emails-how-to-condense-multiple-blank-not-really-blank-lines-co