3

Data

4. Alendronic acid
A. Antiosteoporotic agent. 
B. Inhibit osteoclast formation and function by inhibiting FPPS enzyme, so increase bone mass. 
C. Osteoporosis in combination with vitamin D. 

5. Aminophylline
A. Methylxanthine. Less potent and shorter-acting bronchodilator than Theophylline. 
B. Phosphodiesterase (PDE) inhibitor, so increase cAMP so affecting calcium so relaxes respiratory SM and dilates bronchi/bronchioles. 
C. Last option of asthma attack, COPD, Reversible airways obstruction. 

which I want to be (and later without the empty line as in the pseudocode below explained)

4. Alendronic acid
A. Antiosteoporotic agent. B. Inhibit osteoclast formation and function by inhibiting FPPS enzyme, so increase bone mass. C. Osteoporosis in combination with vitamin D. 

5. Aminophylline
A. Methylxanthine. Less potent and shorter-acting bronchodilator than Theophylline. B. Phosphodiesterase (PDE) inhibitor, so increase cAMP so affecting calcium so relaxes respiratory SM and dilates bronchi/bronchioles. C. Last option of asthma attack, COPD, Reversible airways obstruction. 

My attempt was originally based on the idea of removing all empty lines by gsed -n "s/^$//;t;p;" but this is not possible now.

Pseudocode

  • remove all newlines (not empty lines) by tr '\n' ' ' (everything now one liners but problem since takes also empty lines!)
  • replace all A. by \nA. by sed 's#A.#\nA.#'
  • remove all empty lines by gsed -n "s/^$//;t;p;"

Pseudocode in summary

cat                                 \
     10.6.2015.tex                  \
                                    \
| tr '\n' ' '                       \
                                    \
| sed 's#A.#\nA.#'                  \
                                    \
| gsed -n "s/^$//;t;p;"             \
                                    \
> 10.6.2015_quizlet.tex

which is however wrong because of the logical mistake in the first line.

How can remove newlines after empty line in Perl/Sed/tr?

2

I would use perl or awk to read the data a paragraph at a time, and remove all but the first newline:

perl -00 -pe '$\="\n\n"; s/\n/\0/; s/\n//g; s/\0/\n/' file

Commented

perl -00 -pe '   # each record is separated by blank lines (-00)
                 # read the file a record at a time and auto-print (-p)
    $\="\n\n";   # auto-append 2 newlines to each record
    s/\n/\0/;    # turn the first newline into a null byte
    s/\n//g;     # remove all other newlines
    s/\0/\n/     # restore the first newline
' file

Similarly

awk -v RS= -F'\n' '{print $1; for (i=2; i<=NF; i++) printf "%s", $i; print ""; print ""}' file
  • I accepted this answer because I like the idea of reading in the data first as blocks and then processing, simplifying much the task. – Léo Léopold Hertz 준영 Jun 9 '15 at 5:51
  • 1
    @Masi; Note that such block definition is also part of the awk solution (with RS=""). (I added an explanation.) – Janis Jun 9 '15 at 6:42
  • @Janis - I think they all do. Well, ok, there's another sed here that does a s///ubstitution test loop - which I guess would depend on how you define block. I personally prefer to block the edits to manageable globally applied sizes whenever possible. sed's pattern/hold spaces can handle at least 4k. – mikeserv Jun 9 '15 at 8:40
2

You can use:

sed '/[0-9]\./{n;:l;N;/\n$/!s/\n/ /;t l}' file

This will output:

4. Alendronic acid
A. Antiosteoporotic agent.  B. Inhibit osteoclast formation and function by inhibiting FPPS enzyme, so increase bone mass.  C. Osteoporosis in combination with vitamin D. 

5. Aminophylline
A. Methylxanthine. Less potent and shorter-acting bronchodilator than Theophylline.  B. Phosphodiesterase (PDE) inhibitor, so increase cAMP so affecting calcium so relaxes respiratory SM and dilates bronchi/bronchioles.  C. Last option of asthma attack, COPD, Reversible airways obstruction. 

Explanation

We match the line with the number and the period with /[0-9]\./. Then we enter a code block, that goes to the next line with n. It starts a loop with :l, that appends the next line with N, and replaces the newline with a space with s/\n/ /. The loop terminates when it reaches an empty line, which is picked up by the condition /\n$/!.

2

Here is an awk solution that solves the issue by appropriate definitions of what's the field and record separators for input and output; thus the effective command ($1=$1 FS) is quite simple:

awk '
  BEGIN { RS="" ; FS="\n" ; OFS="" ; ORS="\n\n" }
  $1=$1 FS
'

Explanation:

RS="" - will handle blocks of empty line separated data as one record

FS="\n" - will define each line of a block as an own addressable field

OFS="" - due to blank terminated data no output field separator necessary

ORS="\n\n" - to separate the new blocks (as the input data) by a blank line

$1=$1 FS - the first field (i.e. first line) will be separated from the rest of the lines in the block by a newline character; as that assignment is a true condition in awk the modified record (block) will be printed

1
sed -n '/^[0-9]/!H;//x;$x;s/\n\([^A]\)/ \1/gp' <infile >outfile

Seems to do the trick:

  1. /^[0-9]/!H
    • If a line does !not begin with a digit, then append it to Hold space following a \newline.
  2. //x;$x
    • If it does begin with a digit, and/or if this is the $last line, exchange pattern and hold spaces.
  3. s/\n\([^A]\)/ \1/gp
    • If 1 or more sequences of a \newline followed by any not-A character can be found in pattern space, then globally s///ubstitute the \newlines in those sequences for a <space> and print the results.
    • The only time a \newline will be found is immediately following an exchange - so only on the lines beginning with a digit or the last line.
    • The leading digit gets to retain its \newline because the separating line is the last character in pattern space when the exchange occurs - and so there is no \([^A]\) character to follow it, and so it does not get s///ubstituted for a space.

And that's all.

OUTPUT:

4. Alendronic acid
A. Antiosteoporotic agent.  B. Inhibit osteoclast formation and function by inhibiting FPPS enzyme, so increase bone mass.  C. Osteoporosis in combination with vitamin D. 

5. Aminophylline
A. Methylxanthine. Less potent and shorter-acting bronchodilator than Theophylline.  B. Phosphodiesterase (PDE) inhibitor, so increase cAMP so affecting calcium so relaxes respiratory SM and dilates bronchi/bronchioles.  C. Last option of asthma attack, COPD, Reversible airways obstruction. 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.