私はこれを持っています:
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:
これを説明する必要があります...
これは不必要に複雑です。したがって、「空行を削除」を{}
別の方法で表現する必要があります。キーコマンドはt
sedがどのように実行するかですif ... then
。T
それは簡単だったでしょうが、GNU sed専用です。私はマニュアルページを引用しています:
t label:最後の入力行を読み込んだ後にas / / /が正常に置き換えられた場合はラベルに分岐し、ラベルが省略された場合は最後のtまたはTコマンド以降にスクリプトの最後に分岐します。
私はその有名なs
命令を乱用しました。何も置換せず、その行が空であることをテストするだけです。したがって、空の行を空の行に置き換えます(とにかく行が削除されるため、何でも代替として使用できます)。
s
「交換」が完了すると、行は空になります。この場合、d
コマンドを実行する必要があります。そうでなければ何もできません。t
アクションの実行中にジャンプがないため、スクリプトの最後にジャンプするには分岐s
コマンドが必要です。支店のターゲットです。暗黒時代(sedが発明されたとき…テヒ)のようです。b
: label
goto
別のオプションは、s
空でないすべての行を「置換」してs
コマンドをより複雑にし、残りの部分をより簡単にすることです。
sed '5,${s/^\(..*\)$/\1/; t end; d; : end;}' input
^..*$
これは「空白ではない行」を意味し、\1
「最初の括弧の内容」を意味します。