我会注意到,在我当前的语言环境中,这个脚本似乎不适用于我的sed
(GNU sed 4.1.5) 副本。如果我用它运行LC_ALL=C
它工作正常。
这是脚本的注释版本。 sed
基本上有两个寄存器,一个称为“模式空间”,用于(基本上)当前输入行,另一个是“保持空间”,可由脚本用于临时存储等。
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:]]