如何通过 sed 从 beginning/end 文件中 trim 连续空格

how to trim consecutive whitespace from beginning/end of file via sed

使用 sed,我如何 trim 一个或多个 连续 仅空白行从文件的开头 and/or 结束? ("whitespace-only" 是指不包含任何非空白字符的行,即空白或仅包含空白字符的行。)

例如,如果我的文件是:

<blank line>
<line only containing some space/tab characters>
<blank line>
foo
bar
<tab character>
baz
<space character>
<space character><tab character>
qux
<tab character>

那么所需的输出将是:

foo
bar
<tab character>
baz
<space character>
<space character><tab character>
qux

如果 trim 从文件的开头和结尾开始必须在单独的 sed 调用中完成,那没关系,尽管我也对在其中管理所有内容的解决方案感兴趣一次调用。

P.S。这在 Perl / Ruby 等中很容易,但我特别想知道在 sed 中是否可行。谢谢!

我还没有看到任何真正的 sed 专家提出解决方案,所以这是我的尝试(GNU sed 具体由于 \S\s - 替换为 [^[:space:]][[:space:]]分别为POSIX):

$ sed -e '/\S/,$!d' -e :a -e '/^\s*$/{$d;N;ba' -e '}' file
foo
bar

baz


qux

如果有人想看到一种明智的方法来与最终调用的任何神秘的 sed 咒语进行比较,这是使用 GNU awk 进行多字符 RS\s [的缩写的一种方法=19=]:

$ awk -v RS='^$' '{gsub(/^\s+|\s+$/,"")}1' file
foo
bar

baz


qux

POSIX 等价于如果您乐于选择一些您知道不能出现在输入中的控制字符(例如使用 ^C = 文字 control-C 字符):

awk -v RS='^C' '{gsub(/^[[:space:]]+|[[:space:]]+$/,"")}1' file

否则:

awk '{rec=rec [=13=] RS} END{gsub(/^[[:space:]]+|[[:space:]]+$/,"",rec); print rec}' file

或者如果您的内存有限并且无法一次读取整个文件,您需要 2 遍才能确定最后一个非空行的位置,例如:

awk 'NR==FNR{if(NF){if(!beg)beg=NR; end=NR}; next} (FNR>=beg)&&(FNR<=end)' file file

或者您需要缓冲空行(在它们的初始集合之后),直到您遇到非空行,然后在当前行之前打印该缓冲区:

awk 'NF{printf "%s%s\n",buf,[=15=]; buf=""; f=1; next} f{buf = buf [=15=] RS}' file