7.21 連続する空行の圧縮

最後の例として、「cat -s」と同じ機能、つまり連続する空行を圧縮する3つのスクリプトを示します。後のものほど複雑になり、速度も上がります。

最初のものは、先頭と末尾に空行があれば、それぞれ1行を残します。

#!/usr/bin/sed -f

# on empty lines, join with next
# Note there is a star in the regexp
:x
/^\n*$/ {
N
bx
}
コード内の説明(日本語訳)

空行なら次の行と結合します。正規表現にアスタリスクがあることに注意してください。


# now, squeeze all '\n', this can be also done by:
# s/^\(\n\)*/\1/
s/\n*/\
/
コード内の説明(日本語訳)

すべての「\n」を圧縮します。コメントに示すs/^\(\n\)*/\1/でも行えます。

次のものは少し複雑で、先頭の空行をすべて削除します。末尾に空行があった場合は、1行を残します。

#!/usr/bin/sed -f

# delete all leading empty lines
1,/^./{
/./!d
}
コード内の説明(日本語訳)

先頭の空行をすべて削除します。


# on an empty line we remove it and all the following
# empty lines, but one
:x
/./!{
N
s/^\n$//
tx
}
コード内の説明(日本語訳)

空行では、その行と後続の空行を、1行だけ残して取り除きます。

最後のものは、先頭と末尾の空行を取り除きます。また、これが最も高速です。ループをすべてnとbで処理し、行の終わりでスクリプトを自動的に再開するsedに頼っていないことに注目してください。

#!/usr/bin/sed -nf

# delete all (leading) blanks
/./!d
コード内の説明(日本語訳)

すべての先頭の空行を削除します。


# get here: so there is a non empty
:x
# print it
p
# get next
n
# got chars? print it again, etc...
/./bx
コード内の説明(日本語訳)

ここに到達したということは、空でない行があります。それを出力し、次の行を取得します。文字があれば、それも出力する、という処理を繰り返します。


# no, don't have chars: got an empty line
:z
# get next, if last line we finish here so no trailing
# empty lines are written
n
# also empty? then ignore it, and get next... this will
# remove ALL empty lines
/./!bz
コード内の説明(日本語訳)

文字がなければ、空行が見つかったということです。次の行を取得します。最終行ならここで終了するため、末尾の空行は出力されません。次も空行なら無視し、さらに次の行を取得します。これによって、すべての空行を取り除きます。


# all empty lines were deleted/ignored, but we have a non empty.  As
# what we want to do is to squeeze, insert a blank line artificially
i\
コード内の説明(日本語訳)

すべての空行が削除または無視され、空でない行が見つかりました。目的は空行の圧縮なので、ここで空行を1行挿入します。


bx