【问题标题】:Strip blank lines from first n lines using sed使用 sed 从前 n 行中删除空白行
【发布时间】:2015-05-20 09:00:13
【问题描述】:

我只需要从文本文件的前 6 行中删除空白行。我尝试使用this StackOverflow questionthis file 拼凑一个解决方案,但无济于事。

这是我正在使用的 sed 脚本(别名为 faprep='~/misc-scripts/fa-prep.sed),最后一个命令是失败的:

#!/opt/local/bin/sed -f

# Title Treatments
s|<\(/\?\)h1[^>]*\?>|[\1b]|g    # Replace <h1></h1> with [b][/b] for saga titles
s|<\(/\?\)h2[^>]*\?>|[\1i]|g    # Replace <h2></h2> with [i][/i] for arc titles
s|</\?h3[^>]*\?>||g             # Strip <h3 id=""></h3> out without removing chapter title text

# HTML tag strips & substitutions
s|</\?p>||g                 # Strip all <p></p> tags
s|<\(/\?\)em>|[\1i]|g       # Change <em></em> to [i][/i]
s|<\(/\?\)strong>|[\1b]|g   # Change <strong></strong> to [b][/b]

# Character code substitutions
s/&\#822[01];/\"/g  # Replace &#8220; and &#8221; with straight double quote (")
s/&\#8217;/\'/g     # Replace &#8217; with straight single quote (')
s/&\#8230;/.../g    # Replace &#8230; with a 3-period ellipsis (...)
s/&\#821[12];/--/g  # Replace &#8212; with a 2-hyphen em dash (--)

# Final prep; stripping out unnecessary cruft
/<body>/,/<\/body>/!d   # Delete everything OUTSIDE the <body></body> tags
/<\/\?body>/d           # Then, delete the body tags :3

# Pay attention to meeeeeeee!!!!
1,6{/./!d}      # Remove blank lines from around titles??

这是我从终端运行的命令,它显示最后一行未能从文件的前 6 行中去除空格(当然,在进行了所有其他修改之后):

calyodelphi@dragonpad:~/pokemon-story/compilations $ ch='ch6'; faprep $ch-mmd.html > $ch-fa.txt; head -6 $ch-fa.txt

[b]Hoenn Saga (S1)[/b]

[i]Next City Arc (A2)[/i]

Chapter 6: A Peaceful City Stroll... Or Not
calyodelphi@dragonpad:~/pokemon-story/compilations $

文件的其余部分由第三个标题后的空行和所有由空行分隔的段落组成。我想保留那些空行,这样只有最顶部的标题之间的空行会被剥离。

只是为了澄清几点:这个文件有 Unix 行结尾,并且这些行应该没有空格。即使在显示空白的文本编辑器中查看,每个空白行也只包含一个换行符。

【问题讨论】:

  • 疯狂猜测:输入文件是否有 windows 行结尾? (您可能在使用 cygwin 吗?)哦,只是为了确定:这些行中没有空格,是吗?
  • 刚刚编辑了我的问题来回答你的问题。 ^..^ 它们是 unix 结尾(Mac OS X),空行仅包含换行符。
  • MacOS X 的 sed 对很多事情都有些挑剔。我想你需要一个分号——试试1,6{/./!d;},这行得通吗?尽管在这种情况下我预计 sed 会抱怨语法错误。
  • 用正则表达式解析 HTML:stackoverflow.com/a/1732454/7552
  • @CalyoDelphi 你会这么认为,但不是。使用第二个 sed 进程是一种解决方案,但我可以制作一些东西来保持它在一个中。稍等片刻。

标签: regex sed


【解决方案1】:

由于 cmets 中的讨论清楚地表明您希望忽略 body 标记的前六行中的空行 - 换句话说,到达该部分脚本的前六次 - 而不是整体输入数据的前六行,不能使用全局行计数器。由于您没有使用保持缓冲区,我们可以使用它来构建我们自己的计数器。

所以,替换

1,6 { /./! d }

x               # swap in hold buffer
/.\{6\}/! {     # if the counter in it hasn't reached 6
  s/^/./        # increment by one (i.e., append a character)
  x             # swap the input back in
  /./!d         # if it is empty, discard it
  x             # otherwise swap back
}
x               # and swap back one more time. This dance ensures that the
                # line from the input is in the pattern space when we drop
                # out at the bottom to the printing, regardless of which
                # branches were entered.

或者,如果这看起来太复杂,请使用@glennjackman 的建议并将第一个 sed 脚本的输出通过sed '1,6 { /./! d; }' 传输,因为第二个进程将有自己的行计数器处理预处理数据。这没有什么好玩的,但它会起作用的。

【讨论】:

  • 啊,您的一位 cmets 实际上为我指出了一个不同的解决方案的正确方向! (我将在回答我自己的问题时提供)但是我的室友浏览了您的解决方案并称赞它也是一种可行的方法。 :)
【解决方案2】:

这个答案由@Wintermute 的 cmets 提供,我的问题为我指明了正确的方向!当我将删除语句放在最后时,我错误地认为 sed 正在处理修改后的流。当我尝试使用不同的地址(9,14 行)时,它运行良好,但对我来说太老套了。但这证实了我需要将流视为仍然包含我认为已经消失的行。

因此,我将删除语句移到了清除 &lt;body&gt; 标记及其之外的所有内容的语句之上,并使用了正则表达式和 addr1,+N trick here 来生成最终结果:

脚本:

#!/opt/local/bin/sed -f

# Title Treatments
s|<\(/\?\)h1[^>]*\?>|[\1b]|g    # Replace <h1></h1> with [b][/b] for saga titles
s|<\(/\?\)h2[^>]*\?>|[\1i]|g    # Replace <h2></h2> with [i][/i] for arc titles
s|</\?h3[^>]*\?>||g             # Strip <h3 id=""></h3> out without removing chapter title text

# HTML tag strips & substitutions
s|</\?p>||g                 # Strip all <p></p> tags
s|<\(/\?\)em>|[\1i]|g       # Change <em></em> to [i][/i]
s|<\(/\?\)strong>|[\1b]|g   # Change <strong></strong> to [b][/b]

# Character code substitutions
s/&\#822[01];/\"/g  # Replace &#8220; and &#8221; with straight double quote (")
s/&\#8217;/\'/g     # Replace &#8217; with straight single quote (')
s/&\#8230;/.../g    # Replace &#8230; with a 3-period ellipsis (...)
s/&\#821[12];/--/g  # Replace &#8212; with a 2-hyphen em dash (--)

# Final prep; stripping out unnecessary cruft
/<body>/,+6{/^$/d}      # Remove blank lines from around titles
/<body>/,/<\/body>/!d   # Delete everything OUTSIDE the <body></body> tags
/<\/\?body>/d           # Then, delete the body tags :3

结果输出:

calyodelphi@dragonpad:~/pokemon-story/compilations $ ch='ch6'; faprep $ch-mmd.html > $ch-fa.txt; head -6 $ch-fa.txt
[b]Hoenn Saga (S1)[/b]
[i]Next City Arc (A2)[/i]
Chapter 6: A Peaceful City Stroll... Or Not

The next two weeks of training passed by too quickly and too slowly at the same time. [rest of paragraph omitted for space]

calyodelphi@dragonpad:~/pokemon-story/compilations $

感谢@Wintermute! :D

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-05-01
    • 2017-03-27
    • 2014-10-16
    • 2020-11-04
    • 2011-05-30
    • 2022-01-03
    • 2018-06-07
    • 1970-01-01
    相关资源
    最近更新 更多