5行目から空白行を削除する方法

5行目から空白行を削除する方法

私はこれを持っています:

sed -i '/^$/d' temp_spec.rb

これは空の行を削除し、うまく機能します。 5-999行(またはファイルの終わりの5行)に対してのみこれを行うにはどうすればよいですか?

私は試した:

sed -n5,999 -i '/^$/d' temp_spec.rb
sed '5,999!d/^$/d' temp_spec.rb

ただし、どちらも機能しません(エラーなし)。

答え1

5行目から始めてすべての空行を削除し、1行から4行を維持するには、次のようにします。

sed -i '5,${;/^$/d;}' temp_spec.rb

{グループ化演算子なので、最初のコマンドは「一致するまで5,${5行目からinput()の終わりまで$次のコマンドを実行します}」を意味します。{との間の命令には}アドレスが前に付くこともあるので、内部命令は「/^$/d行の先頭( )と終わり( )の間に何もなければ削除する」という意味です。 sedコマンドは区別できます。 (これはsedの正しく文書化されていない機能です。ほとんどのsed実装はこれをサポートしますが、^$;完全にポータブルではない.) Haukeが指摘したように、;後者{はオプションですが、前者}は必須です。

5行目から始まるすべての空行を削除し、1行から4行を削除するには、次の方が簡単です。

sed -i '1,4d;/^$/d' temp_spec.rb

答え2

awkを使用する別のオプション:

awk 'NR<5||/./'

答え3

sed '5,${s/^$//; t delete; b end; : delete; d; : end;}' temp_spec.rb

編集1:

これを説明する必要があります...

これは不必要に複雑です。したがって、「空行を削除」を{}別の方法で表現する必要があります。キーコマンドはtsedがどのように実行するかですif ... thenTそれは簡単だったでしょうが、GNU sed専用です。私はマニュアルページを引用しています:

t label:最後の入力行を読み込んだ後にas / / /が正常に置き換えられた場合はラベルに分岐し、ラベルが省略された場合は最後のtまたはTコマンド以降にスクリプトの最後に分岐します。

私はその有名なs命令を乱用しました。何も置換せず、その行が空であることをテストするだけです。したがって、空の行を空の行に置き換えます(とにかく行が削除されるため、何でも代替として使用できます)。

s「交換」が完了すると、行は空になります。この場合、dコマンドを実行する必要があります。そうでなければ何もできません。tアクションの実行中にジャンプがないため、スクリプトの最後にジャンプするには分岐sコマンドが必要です。支店のターゲットです。暗黒時代(sedが発明されたとき…テヒ)のようです。b: labelgoto

別のオプションは、s空でないすべての行を「置換」してsコマンドをより複雑にし、残りの部分をより簡単にすることです。

sed '5,${s/^\(..*\)$/\1/; t end; d; : end;}' input

^..*$これは「空白ではない行」を意味し、\1「最初の括弧の内容」を意味します。

関連情報