sed
このスクリプトは、現在のロケールの (GNU sed 4.1.5) のコピーでは機能しないようです。私がそれを実行すると、正常に動作しLC_ALL=C
ます。
これは、スクリプトの注釈付きバージョンです。 sed
基本的に 2 つのレジスタがあり、1 つは「パターン スペース」と呼ばれ、(基本的に) 現在の入力行に使用され、もう 1 つは「ホールド スペース」であり、スクリプトで一時的な格納などに使用できます。
sed -n ' # -n: by default, do not print
G # Append hold space to current input line
s/\n/&&/ # Add empty line after current input line
/^\([ -~]*\n\).*\n\1/d # If the current input line is repeated in the hold space, skip this line
# Otherwise, clean up for storing all input in hold space:
s/\n// # Remove empty line after current input line
h # Copy entire pattern space back to hold space
P # Print current input line'
空行の追加と削除は、中央のパターンを比較的単純に保つためにあると思います (現在の行の後、一致する行の先頭の前に改行があると期待できます)。
したがって、基本的には、入力ファイル全体 (複製を除く) が (逆の順序で) ホールド スペースに保持され、パターン スペースの最初の行 (現在の入力行) がパターン スペースの残りの場所 (これはスクリプトがこの行の処理を開始したときに保留スペースからコピーされた)、それをスキップして最初からやり直します。
条件の正規表現はさらに分解できます。
^ # Look at beginning of line (i.e. beginning of pattern space)
\( # This starts group \1
[ -~] # Any printable character (in the C locale)
* # Any number of times
\n # Followed by a newline
\) # End of group \1 -- it contains the current input line
.*\n # Skip any amount of lines as necessary
\1 # Another occurrence of the current input line, with newline and all
このパターンが一致する場合、スクリプトはパターン スペースを破棄し、次の入力行からやり直します ( d
)。
[ -~]
に変更することで、ロケールに関係なく動作させることができます[[:print:]]