数据
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.
我想要的(稍后没有空行,如下面解释的伪代码所示)
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.
我的尝试最初是基于删除所有空行的想法,gsed -n "s/^$//;t;p;"
但现在这是不可能的。
伪代码
- 删除所有换行符(不是空行)
tr '\n' ' '
(现在所有内容都是一个衬垫,但问题是因为也需要空行!) - 全部替换A。经过\nA.经过
sed 's#A.#\nA.#'
- 删除所有空行
gsed -n "s/^$//;t;p;"
伪代码总结
cat \
10.6.2015.tex \
\
| tr '\n' ' ' \
\
| sed 's#A.#\nA.#' \
\
| gsed -n "s/^$//;t;p;" \
\
> 10.6.2015_quizlet.tex
然而,由于第一行的逻辑错误,这是错误的。
如何在 Perl/Sed/tr 中删除空行后的换行符?
答案1
我会使用 perl 或 awk 一次读取一段数据,并删除除第一个换行符之外的所有内容:
perl -00 -pe '$\="\n\n"; s/\n/\0/; s/\n//g; s/\0/\n/' file
评论过
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
相似地
awk -v RS= -F'\n' '{print $1; for (i=2; i<=NF; i++) printf "%s", $i; print ""; print ""}' file
答案2
您可以使用:
sed '/[0-9]\./{n;:l;N;/\n$/!s/\n/ /;t l}' file
这将输出:
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.
解释
我们将行与数字相匹配,将句点与 相匹配/[0-9]\./
。然后我们输入一个代码块,该代码块转到下一行n
。它以 开始一个循环:l
,用 附加下一行N
,并用 替换换行符s/\n/ /
。当循环到达空行时终止,该空行由条件选取/\n$/!
。
答案3
这是一个awk
解决方案,通过适当定义输入和输出的字段和记录分隔符来解决该问题;因此有效的命令 ( $1=$1 FS
) 非常简单:
awk '
BEGIN { RS="" ; FS="\n" ; OFS="" ; ORS="\n\n" }
$1=$1 FS
'
解释:
RS=""
- 将空行分隔数据块作为一条记录处理
FS="\n"
- 将块的每一行定义为自己的可寻址字段
OFS=""
- 由于空白终止数据,无需输出字段分隔符
ORS="\n\n"
- 用空行分隔新块(作为输入数据)
$1=$1 FS
- 第一个字段(即第一行)将通过换行符与块中的其余行分隔开;因为该分配是awk
修改记录(块)中的真实条件,因此将被打印
答案4
sed -n '/^[0-9]/!H;//x;$x;s/\n\([^A]\)/ \1/gp' <infile >outfile
似乎可以解决这个问题:
/^[0-9]/!H
- 如果一行不
!
以数字开头,则将其附加到新行H
后面的旧空格中\n
。
- 如果一行不
//x;$x
- 如果它确实以数字开头,和/或如果这是
$
最后一行,则x
更改模式和h
旧空格。
- 如果它确实以数字开头,和/或如果这是
s/\n\([^A]\)/ \1/gp
- 如果 1 个或多个 ewline 序列
\n
后跟任何非A可以在模式空间中找到字符,然后g
全局s///
替换\n
这些序列中的 ewlines<空格>并p
打印结果。 - 唯一一次
\n
会在 e 更改之后立即找到 ewlinex
- 因此仅在以数字开头的行或最后一行上。 - 前导数字保留其
\n
前行,因为分隔线是最后的当 ex
发生变化时,模式空间中的字符 - 因此没有\([^A]\)
字符跟随它,因此它不会被s///
空格替代。
- 如果 1 个或多个 ewline 序列
就这样。
输出:
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.