36

私はこの質問と答えを見つけて、3つの空の行を削除する方法について答えました。ただし、2つの空の行にのみ同じものが必要です。つまり。二重の空白行はすべて完全に削除する必要がありますが、単一の空白行は保持する必要があります。

私は少しsedを知っていますが、3つの空白行を削除するために提案されたコマンドは私の頭の上にあります:

sed '1N;N;/^\n\n$/d;P;D'

4

8 に答える 8

72

これは次の場合に簡単になりますcat

cat -s
于 2013-04-22T07:45:22.433 に答える
19

私はsedあなたが理解していないコマンドにコメントしました:

sed '
    ## In first line: append second line with a newline character between them.
    1N;
    ## Do the same with third line.
    N;
    ## When found three consecutive blank lines, delete them. 
    ## Here there are two newlines but you have to count one more deleted with last "D" command.
    /^\n\n$/d;
    ## The combo "P+D+N" simulates a FIFO, "P+D" prints and deletes from one side while "N" appends
    ## a line from the other side.
    P;
    D
'

1N'stack'には2行しか必要なく、2番目の行で十分なので、削除しN、に変更/^\n\n$/d;/^\n$/d;て、2つの連続する空白行をすべて削除します。

テスト:

内容infile

1


2
3

4



5

6


7

sed次のコマンドを実行します。

sed '
    N;
    /^\n$/d;
    P;
    D
' infile

その結果、次のようになります。

1
2
3

4

5

6
7
于 2012-09-26T10:41:23.027 に答える
8
sed '/^$/{N;/^\n$/d;}'

ファイル内の2つの連続する空白行のみが削除されます。この式はファイルでのみ使用でき、完全に理解できるのはあなただけです。空白行が来ると、中括弧に入ります。

通常、sedは1行を読み取ります。N2行目をパターンスペースに追加します。その行が空の行の場合。両方の行は改行で区切られます。

/^\n$/このパターンはその時間に一致し、のみ機能しdます。そうdでなければ動作しません。dパターンスペースのコンテンツ全体を削除してから、次のサイクルを開始するために使用されます。

于 2012-09-28T06:19:23.567 に答える
7

これは次の場合に簡単になりますawk

awk -v RS='\n\n\n' 1
于 2012-09-26T10:47:20.333 に答える
1

ただし、上記の解決策では、3つの連続する空白行の最初の検索のみが削除されます。すべてを削除するには、以下のコマンドを使用して3つの連続した空白行を使用します

sed '1N;N;/^\n\n$/ { N;s/^\n\n//;N;D; };P;D' filename
于 2019-02-28T12:50:51.760 に答える
0

私が知る限り、ここでの解決策はどれも機能しません。@DerMikeによって提案されたようにPOSIXに準拠しておらず(そして、すでに別の変換にcat -s使用している場合は便利ではありません)、 @Bireiによって提案されたように時々必要以上の改行を削除します。sedsed 'N;/^\n$/d;P;D'

代わりに、sed ':L;N;s/^\n$//;t L'動作します。POSIXは、コマンドの分離にsed -e :L -e N -e 's/^\n$//' -e 't L'使用することを指定していないため、POSIX準拠の場合はを使用します。;

例:

$ S='foo\nbar\n\nbaz\n\n\nqux\n\n\n\nquxx\n';\
> paste <(printf "$S")\
>       <(printf "$S" | sed -e 'N;/^\n$/d;P;D')\
>       <(printf "$S" | sed -e ':L;N;s/^\n$//;t L')
foo     foo     foo
bar     bar     bar
                
baz     baz     baz
        qux     
                qux
qux     quxx    
                quxx
                
                
quxx            
$ 

ここでは、元のファイル、@ Bireiのソリューション、および私のソリューションを並べて表示できます。@Bireiのソリューションは、bazとを区切るすべての空白行を削除しますquxが、私のソリューションは、意図したとおりに1つを除くすべてを削除します。

説明:

:L        Create a new label called L.

N         Read the next line into the current pattern space,
          separated by an "embedded newline."

s/^\n$//  Replace the pattern space with the empty pattern space,
          corresponding to a single non-embedded newline in the output,
          if the current pattern space only contains a single embedded newline,
          indicating that a blank line was read into the pattern space by `N`
          after a blank line had already been read from the input.

t L       Branch to label L if the previous `s` command successfully
          substituted text in the pattern space.

事実上、これにより、一度に1つの繰り返し空白行が削除され、それぞれが埋め込み改行としてパターンスペースに読み込まれ、Nで削除されますs

于 2022-01-13T10:29:36.510 に答える
-1

ただし、上記の解決策では、3つの連続する空白行の最初の検索のみが削除されます。すべてを削除するには、以下のコマンドを使用して3つの連続した空白行を使用します

sed '1N; N; / ^ \ n \ n $ / {N; s / ^ \ n \ n //; N; D; }; P;D'ファイル名

于 2019-02-28T13:00:54.717 に答える
-2

'uniq'コマンドにパイプするだけで、空の行の数に関係なく、すべての空の行が1つに縮小されます。シンプルな方が良いです。

明確化:マーラーが述べたように、削除したくない「他の非空白の連続した重複行」がある場合、これは解決策ではありません。これ、構成ファイルをクリーンアップしようとしたときのような他の場合の解決策です。これは、この質問を見たときに私が求めていた解決策でした。私は実際に「uniq」を使用して問題を解決しました。

于 2013-10-07T09:34:30.263 に答える